Vapor Trail

明るく楽しく元気よく

PHPで『テスト駆動開発』

今更感はありますけど、『テスト駆動開発』をコツコツ写経しています。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オブジェクトをキーにしている。

PHPでは連想配列があるが、

$this->rates = [new Pair(from, to) => rate];

みたいにオブジェクトをキーにすることができない。

 

localdisk.hatenablog.com

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))];
}