Born Too Late

Yuya's old tech blog.

MyObject クラスを少し改良?してみた

2010-02-28 06:26:20

昨日投稿したメタプログラミングで PHP をもっとオブジェクト指向にだと、以下のようにしか書けませんでした。

$obj = new MyObject(array('foo', 'bar', 'baz'));
echo $obj->join(',')->strtoupper();
// => FOO,BAR,BAZ

どういうことかというと、new の直後でメソッドを呼び出すことができないようで、上記のように 2 行で書かざるを得なくなっていました。

そこで、MyObject クラスを以下のように書き換えました。

class MyObject
{
    private $_selfMember;

    public function __construct($selfMember)
    {
        $this->_selfMember = $selfMember;
    }

    public static function init($selfMember)
    {
        return new self($selfMember);
    }

    public function __call($name, $args)
    {
        $new_args = array_merge(
            array($this->_getSelfMember()),
            $args
        );
        return new self(call_user_func_array($name, $new_args));
    }

    public function _getSelfMember()
    {
        return $this->_selfMember;
    }

    public function __toString()
    {
        return print_r($this->_selfMember, true);
    }
}

変更点は、init というスタティックメソッドを追加しただけです。

この変更により、以下のように書けるようになりました。

echo MyObject::init(array('foo', 'bar', 'baz'))->join(',')->strtoupper();
// => FOO,BAR,BAZ

楽しいような、危なっかしいような感じですが、言いたいこととしては、マジックメソッドを使うといろいろおもしろいことができそうですよ!ということにさせてください。こういう、いかにも役に立たなそう (というかむしろ害悪になりそう) なコードでも、遊びでいろいろ試しているうちに、実用に耐えうるアイディアに化けるかもしれません・・・。