なんたらノート第三期ベータスマートフォン用の表示で見るスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。読者です読者をやめる読者になる読者になるなんたらノート第三期ベータ2011-07-04PHP5.4とScalaのトレイト比較PHPScalaPHP5.4にはトレイトという文法が導入されて、多重継承の便利さが享受できるようになるそうです。試してみることにしました。トレイトといえば代表選手はScalaですね。Scalaでいうトレイトは、インターフェースの定義とメソッドの実装を同時にやってくれる便利な概念でした。単一継承のOOP言語では「〜は〜の一種」という制約が強すぎて、「ペンギンは鳥の飛行メソッドによって飛行できてしまう」という問題があります。「ペンギンは飛べないが泳げる鳥」を綺麗に解決する必要はあって、その解答として、トレイトのあるScalaではこんな解が導けます。反応するところが等しく振る舞うかを、PHP5.4で調べてみることにします。無反応}はい、反応ありませんこれ。PHP5.4のトレイとは型システムとしては機能していません。そりゃまあ当然で、PHP5.4のトレイトは、使用者側でアドホックにメソッド名の置き換えすらできてしまうので、「必ず特定のメソッドに応答することを保証する」インターフェースとしては使えないです。http://simas.posterous.com/new-to-php-54-traitsというわけで、PHPでScalaのサンプルと同じことをやろうとすると、こうなります。swim\n&quot;;インターフェースで「〜な動物」を示し、トレイトでその実装差分として「〜する能力」を補う感じで、Scalaがひとつのシンタックスでやってくれることを、シンタックスを組み合わせて手動でやるとそれっぽくなりました。Scalaのトレイトは継承できたりメソッドシグネチャ競合時の選択方法があるなど、かなりシンタックスに凝っています。PHPインタプリタでそんなのをやるとパフォーマンスに問題があるような気がしてなりません。Scalaのtraitの実験が怪しい結果になったので、エイリアスできると言い切れなくなりました。少なくともインターフェースは限定するのですでにダックタイピングに対応して作られたライブラリが、インターフェースにがっつり来られると困る、という場合もあるかもしれませんし。いうわけでPHPでは、インターフェースと実装差分を完全に切り分けて、そのあたりの問題をシンタックスで解決するのを避けたのかなと思いました。それはたぶんそんなに悪くない(PHPはこの「そんなに悪くない」が大事)選択なんじゃないかと思います。ここで、「同じ泳げる鳥でも、白鳥とペンギンでは意味が違う」という問題を出します。白鳥は水面を泳ぎ、ペンギンは水中を泳ぎますね。言葉上は同じでも、その実現方法はだいぶ違っています。Scalaではこういうとき、トレイトを継承します。あるけれど、少し見た目が悪くなりました。PHP5.4の方法ではこうです。まま、実装差分を切り替えて機能を変更しました。オブジェクト指向言語としては、本物のトレイトに比べると美しくないですが、現実的なやりかただと思いませんか。それどころか、Scalaのそれよりも宣言に変化が少なくて済みました。派生クラスで使い分けされる様子を。PHPの正義はとにかくさっさと使えることです。「トレイトとはメインの継承概念に付随する属性概念でありうんぬんかんぬん」とモデリングにまる1日かけて完璧な言語を目指すことより、「あー、毎回このセキュリティ設定メソッドを全コントローラクラスにコピペするのは面倒だなー。一箇所変えたらメソッド全部書き換わったらいいのに。classの直下にrequire書けないかな」を達成するのがPHPですよね。ついでに、PythonとRubyでも同じことをしてみました。swan.swim()Pythonの多重継承はScalaのトレイトに似ています。いうか実は逆に、Scalaのトレイトが多重継承のスーパーセットを目指して設計されているのが実際なんですけどね。#{swan.swim}&quot;Rubyのmix-inがまさにちょうど、PHP5.4のtraitオンリー版(インターフェースによる制約のまったくない完全なダックタイピング)と似ています。mixinを持っているかどうかの判別にis_aを使えるぶん、PHP5.4のよりもやや型っぽいですが、本質的には型制約じゃないイメージ。いう意味では、PHP5.4は(いつものように)実はちょっと用語選択を間違っているのかも。組み合わせて上手に使うことを、概念上の言葉として「トレイト」と呼ぶのが本当なんだろうなと、そんな気がしないでもないです。いえばちなみに、あてずっぽうで動かしたこんなコードがPHP5.4.0alpha1で動作しました。ReflectionObject($pingu);print_r($ref-&gt;getInterfaces());print_r($ref-&gt;getTraits());そうとう頑張れば、「特定のトレイトを持っているかどうか」をマーカーインターフェース的に使って、挙動の判別に使うことはできるかもしれません。ユーザコードでやるようなことではないので、そこは次世代のフレームワークに任せたほうがいいですね。ところで次世代っていつの話やねん。最後に、PHP5.4.0を単体でCLI実行する気にさせてもらえたあの記事に感謝します。Blog|ブログを報告する。