そもそも、静的型付けでない言語は好きではないのですが、好き嫌いを言っていると仕事が無くなってしまうので・・
そんなわけで、Eclipse(PDT)でPHPのコードを書くわけですが、時にあるクラスのインスタンスの配列を関数/メソッドに渡す形にしたい時があります。
<?php class A { /** * ID * @var int */ public $id; /** * 名前 * @var string */ public $name; }
<?php function a0(array $a) { foreach ($a as $aa) { // A のインスタンスである保証がないし、 // Eclipseで変数名候補を表示させたりできない(重要!!) var_dump($aa->name); } }
この時、関数「a0」内の変数「$aa」が何であるかという保証は何もありませんので、何らかのチェックをする必要があります。
PHPにはtype hintingという機能があり、以下のように書ければいいのですが・・
<?php // 実際にはエラーになる function a0(A[] $a) { // ・・・ }
<?php // 実際にはエラーになる function a0(multitype:A $a) { // ・・・ }
<?php // 実際にはエラーになる function a0(array(A) $a) { // ・・・ }
そんなわけで、Eclipse(PDT)をだますために、ひと工夫したりします。
instanceofで判定する
<?php function a1(array $a) { foreach ($a as $aa) { if ($aa instanceof A) { var_dump($aa->name); } } }
こうすると、「$aa」はクラスAのインスタンスであることが保証されるので、Eclipse(PDT)がそれを解釈して「$aa」をクラスAのインスタンスとして変数名候補の列挙などをしてくれます。
フィルタ用の関数を作る
<?php function a2(array $a) { $a = filterA($a); foreach ($a as $aa) { var_dump($aa->name); } } /** * * @param array $a * @return multitype:A */ function filterA(array $a) { $res = array(); foreach ($a as $aa) { if ($aa instanceof A) { $res[] = $aa; } } return $res; }
ポイントは、関数「filterA」のdocument comment内の「@return multitype:A」です。 この関数を通してやることにより、戻り値がクラスAのインスタンスであることが一応保証されるので、Eclipse(PDT)をだますことができます。
実際のところ、皆さんはこの問題をどうやって乗り越えているんでしょうか・・