読者です 読者をやめる 読者になる 読者になる

成らぬは人の為さぬなりけり

エンジニアライフをエンジョイする為のブログ

Ruby2.0の新機能を勉強してみる その2 Module#prepend

前回は、キーワード引数をテーマにしました。
で、次は遅延リストを書こうかと思ったんですが。
Module#prependの方が面白かったので、
今日はこっちを書きたいとおもいます。

今回のテーマ

「Module#prepend」

環境

prependって何してくれるの?

と、いうわけで、このメソッドですが、mixin用のメソッドです。
どういう事をしてくれるか、簡単に言うと、
メソッドを上書きできるようなメソッドです。

もっと言うと、メソッド探索順序の一番最初に割り込む事ができます。

includeとは違うの?

includeでmixinする場合、どうなるか、
コード例を挙げて見てみたいとおもいます。

これの実行結果は、以下のようになります。

foo

この場合のメソッド探索順序としては、


Foo > Hoge > Parent

となります。
これも試してみましょう。

superを読んだ結果をくっつけるようにしてみました。
実行結果は以下のようになります。

foohogeparent

この結果から


Foo > Hoge > Parent

の順で探している事が分かります。

prependはどうなるの?

では、今回の本題、prependを使ってみたいと思います。

先ほどのFooクラスのincludeをprependにした、Barクラスを定義してみました。
実行結果は以下のようになります。

hoge

先程の例では、自分自身のnameが一番優先されていましたが、
今回はprependしたHogeのnameが一番に来ています。
つまり、メソッド探索順序の一番最初に割り込んだわけです。
ちなみに、順序は以下のようになります。


Hoge > Bar > Parent

では、これも試してみます。

実行結果は、以下のようになります。

hogebarparent

最後に一つ試してみる

一個気になったので、実験してみました。

prependしてるクラスを継承した子クラスからの順序はどうなるのか。
実行結果はこちら。

piyohogebarparent

まぁ、当然そうなりますよね。

最後の最後にもうひとつ!

では、これはどうなるでしょうか??

最初の予想では

hogepiyohogebarparent

になるかと思ったんですが、違いました。
こうなりました。

piyohogebarparent

ふむ。
ちなみに、「Piyo.ancestors」はこうなります。

[Piyo, Hoge, Bar, Parent, Object, Kernel, BasicObject]

ちなみに、includeの場合

これは、

Last!!!!foohogeparent
[LastSample, Foo, Hoge, Parent, Object, Kernel, BasicObject]

includeは
instance method Module#include
ここに書かれている通り、継承関係に割り込むので、当然こうなりますよね。


D < C < B < C < A

みたいなおかしな継承関係は無理ですから。

おそらくprependも同じなんでしょうね。

ちなみに、
class Module
ここにprependが書かれていないのは何故でしょうね?

今日はこの辺までにしたいと思います。