今更感はありますけど、『テスト駆動開発』をコツコツ写経しています。PHPを使いたいのでPHPで書いているんですけど、本ではJavaで実装されていて12章あたりからちょっとつまづいてます。Javaではクラスをキャストしたり、プロパティに型書いたり、HashMapのキーにオブジェクトを入れたりしていて、これPHPで同じようなことできるのか・・・?と思いはじめた。
private Map<Pair, Integer> rates = new HashMap<>();
...
void addRate(String from, String to, int rate){
rates.put(new Pair(from, to), rate)
}
int rate(String from, String to){
if(from.equals(to)) return 1;
return rates.get(new Pair(from, to));
}
13章でHashMapが現れてきて、Pairオブジェクトをキーにしている。
$this->rates = [new Pair(from, to) => rate];
みたいにオブジェクトをキーにすることができない。
HashMapを作っていた方がいたので使ってみたが、
$this->rates = new HashMap();
$this->rates->put(new Pair($from, $to), $rate);
Illegal offset type
オブジェクトをキーにはできないようだった。
シリアル化すれば使えた。
public function addRate(string $from, string $to, int $rate): void
{
$this->rates = new HashMap();
$this->rates->put(serialize(new Pair($from, $to)), $rate);
var_dump(serialize(new Pair($from, $to)));
}
public function rate(string $from, string $to): int
{
var_dump(serialize(new Pair($from, $to)));
return $this->rates->get(serialize(new Pair($from, $to)));
}
PHP: SplObjectStorage - Manual
SplObjectStorage クラスは、オブジェクトをデータに対応させたり、 データを渡さずオブジェクトセットとして使用したりします。 これらはどちらも、オブジェクトを一意に特定したい場合に便利です。
これこれ!と思って試してみたが、
public function addRate(string $from, string $to, int $rate): void
{
$this->rates = new SplObjectStorage();
$this->rates->attach(new Pair($from, $to), $rate);
}
public function rate(string $from, string $to): int
{
var_dump($this->rates->contains(new Pair($from, $to)));
return $this->rates->offsetGet(new Pair($from, $to));
}
bool(false)
値が取り出せなかった。なぜなのだろうか・・・。
結局、オブジェクトをシリアル化して連想配列のキーとしたが、これでいいのだろうか。。。
public function addRate(string $from, string $to, int $rate): void
{
$this->rates = [serialize(new Pair($from, $to)) => $rate];
}
public function rate(string $from, string $to): int
{
return $this->rates[serialize(new Pair($from, $to))];
}