PHPでメソッドを動的に生やそう - Qiita
個人的結論から言えば、PHPは恐らく「言語の質的」に拡張メソッドとは相性が悪い。
それが反論に現れてる。故に反論の理由もある程度忖度はできる。
反論への忖度
・extendsしたあとで基底クラスにメソッド追加したら死ぬ。
死にません。が言いたいのは判る。
PHPは、モジュール間結合がランタイムかつincludeである、というキモい特徴があり、実行するその瞬間まで、そのメソッドが何処の何者なのか、マジで解らないという駄目な特徴がある。
故に、PSR1やらPHPDOCで「運用で回避」してるわけだ。
それをこれ以上脅かすなと、そういうことだろう。
ちなみにC#では、拡張メソッドはnamespaceの中で定義するものなので、それを指定しないと使えません。
・privateを簡単に見れるようになってカプセル化が死ぬ。
死にません。拡張メソッドに対する誤解。本来の拡張メソッドはprivateを叩けません。関数スタイル呼び出しのsyntax sugerなだけ。
ただカプセル化==privateはちょっと考え方が古いかねえ。その証拠に最近の新言語は、クラス外での関数定義を基本構文としてる。rustとかgoとかがそうだ。
・JSじゃないんだから普通にextendsすりゃええやん。
実際その通りなんだが、本当にそれが可能な場合だけですか?って話なわけさ。arrayをこねくり回す場合って多いでしょ。みんな不満ないのだろうか。
・Kotlinのはただの糖衣構文であって、実際にクラスを変更しているわけではない。
ソーですネ。だから複雑化しないはず。・複雑化するリスクに対してベネフィットが少なすぎる。
しません。そもそも乱用したいわけではないので。・バックポートに使えそう。たとえばSplFileObjectはPHP5.1.0で実装されたがSplFileObject::freadはPHP5.5.11で追加された。
そうそう。そういう感じで使うのがただしい。オリジナル(バイナリ)をいじらずに、何か処理を足すのは、拡張メソッドの本来の遣い方に近い。そこextendsでいいやとか言われちゃ。・runkit_method_addやuopz_add_functionで同じことができるよ。
その通りだけど、プロダクション版でそんな冒険したくないわけさ。断言:拡張メソッド自体は便利なのは間違いない※PHPは追いといて
クラスという「カタチ」にこだわりすぎなんだよね。本来拡張メソッドというものは「任意の型」にメソッドを足せる。どういうことか?
典型的な例でいえば、配列にもメソッドを足せるということだ。ただこれもPHPのではarrayの中身の型を担保する手段がないので、メリットは薄い。まあジェネリック型のタイプヒントをサポートしてからだろう。そして多分その日は来ない。
と小生は思うんだが。
でも総合的には、どうやらPHPの内蔵機能に皆さん不満がないってことなんだろうなあ。
事実、同じ動的言語であるはずのRubyには拡張メソッドがある。
[Ruby]他のクラスを拡張するいろんな方法 - Qiita
クラスという「カタチ」にこだわりすぎなんだよね。本来拡張メソッドというものは「任意の型」にメソッドを足せる。どういうことか?
典型的な例でいえば、配列にもメソッドを足せるということだ。ただこれもPHPのではarrayの中身の型を担保する手段がないので、メリットは薄い。まあジェネリック型のタイプヒントをサポートしてからだろう。そして多分その日は来ない。
- array_search($needle,$haystack,TRUE) !== false #とか毎回書くのバカバカしくね?
- $haystack->hasvalue($needle) # の方が「解りやすい」でしょ?
と小生は思うんだが。
でも総合的には、どうやらPHPの内蔵機能に皆さん不満がないってことなんだろうなあ。
事実、同じ動的言語であるはずのRubyには拡張メソッドがある。
[Ruby]他のクラスを拡張するいろんな方法 - Qiita