わーい、すごーい

たのしーい。

[偉大なる先駆者](http://qiita.com/t_ishida/items/bae7e62950d81f427f13)に捧ぐ。

てかこれ言語の修行にすごく丁度よい気がする。

## 最小構成

[実行結果](http://ideone.com/Ox4Rkp)

```php
<?php

class フレンズ
{
    public static function __callStatic($method, $arguments)
    {
        printf(in_array($method, ['わーい', 'すごーい', 'たのしー'], true) ? '%s%s' : '君は%sがとくいなフレンズなんだね!!%s', $method, \PHP_EOL);
        return get_called_class();
    }
}
フレンズ::わーい()::すごーい()::たのしー()::クソリプ();
```

## モダナイズ

[実行結果](http://ideone.com/DNignA)

```php
<?php

class アニマルガール
{
 
    protected $stack = [];
 
    private final function __construct()
    {}
 
    public static function サンドスター()
    {
        $class_path = get_called_class();
        return new $class_path();
    }
 
    public static function __callStatic($method, $arguments)
    {
        return ($instance ?? $instance = static::サンドスター())->$method();
    }
 
    public function __call($method, $arguments)
    {
        if (in_array($method, ['わーい', 'すごーい', 'たのしー'], true)) {
            $this->stack[] = $method;
        } else {
            $this->stack[] = sprintf('君は%sがとくいなフレンズなんだね！！', $method);
            echo implode(\PHP_EOL, $this->stack), \PHP_EOL;
        }
        return $this;
    }
}
 
アニマルガール::わーい()->すごーい()->たのしー()->クソリプ();
```

## 俺のしたかった納得

[実行結果](http://ideone.com/P9i42z)

```php
<?php

class アニマルガール
{

    const とくいなんだねー = [
        'わーい',
        'すごーい'
    ];

    protected $おぼえてること = [];

    private final function __construct()
    {}

    protected static function サンドスター()
    {
        $class_path = get_called_class();
        return new $class_path();
    }

    public static function __callStatic($method, $arguments)
    {
        return ($instance ?? $instance = static::サンドスター())->$method();
    }

    public function __call($method, $arguments)
    {
        $this->おぼえてること[] = $method !== 'とくい' ? $method : (new class($arguments[0]) {

            const さいしょのおやくそく = '君は%sがとくいなフレンズなんだね！！';

            const すごいおやくそく = '%sができるフレンズなんだー！！';

            public $とくい = null;

            public $ちょっとまえ = アニマルガール::とくいなんだねー[0];

            public function __construct($とくい)
            {
                $this->とくい = $とくい;
            }

            public function __invoke()
            {
                return $this->とくい;
            }

            public function __toString()
            {
                $そうなんだー = sprintf($this->ちょっとまえ === アニマルガール::とくいなんだねー[1] ? self::すごいおやくそく : self::さいしょのおやくそく, $this->とくい);
                $this->ちょっとまえ = アニマルガール::とくいなんだねー[0];
                return $そうなんだー;
            }
        });

        return $this;
    }

    public function __invoke()
    {
        return $this->おぼえてること;
    }

    public function __toString()
    {
        $ちょっとまえ = null;
        foreach ($this->おぼえてること as $じゅんばん => $おぼえてること) {
            if (is_object($おぼえてること)) {
                $this->おぼえてること[$じゅんばん]->ちょっとまえ = $ちょっとまえ;
            } elseif (in_array($おぼえてること, アニマルガール::とくいなんだねー, true)) {
                $ちょっとまえ = $おぼえてること;
            }
        }
        return implode(\PHP_EOL, $this->おぼえてること) . \PHP_EOL;
    }
}

echo アニマルガール::わーい()->すごーい()->たのしー()->とくい('クソリプ');

echo アニマルガール::わーい()->とくい('クソリプ')->すごーい();

echo アニマルガール::すごーい()->とくい('クソリプ')->わーい()->たーのしー();
```