Ruby/Rubyの基礎知識

Ruby2.0の新機能、Module#prependの紹介(2ページ目)

Module#prependが実現するMix-in方式をincludeと比較しながら紹介し、応用編としてRailsのalias_method_chain処理をprependに書き換えます

橋本 拓也

執筆者:橋本 拓也

Rubyガイド

Module#prependで何が出来るようになったのか

私事ですが先日実家の香川県に帰ったところ、うどん屋と田んぼしかない不毛地帯であったのに、いつの間にかセブンイレブンが出店していることに感動しました。具体的な例を使うと記憶しやすいのではないかと考え、これを今回の題材に使ってみることにします。

まずはincludeを使った場合の例です。

SevenElevenモジュールとKagawaクラスにそれぞれ同名のメソッドdrinkが定義されています。Kagawa内でSevenElevenをincludeしたのちKagawa#drinkを呼び出してみると、includeしたSevenElevenのものではなく、Kagawaクラスのdrinkが呼び出されます。

この理由は、Kagawa.ancestorsメソッドを実行することで理解できます。

Object, Kernel, BasicObjectはどんなRubyのクラスにも入ってくる基礎的なクラスです。左が子孫、右が先祖という方向で順に並んでいます。Kagawa#drinkが呼び出されたとき、Rubyは左(子孫)から順にさかのぼってメソッドを探します。先の例ではKagawaクラスのdrinkメソッドがヒットしたのでそこでメソッド探索を打ち切ったのでした。

ここでprependを使うと、メソッド探索においてモジュールのメソッドを先にヒットさせることができます。includeをprependに書き換えると次のようになります。

SevenElevenが先にメソッド探索チェインに現れ、Kagawa2#drinkの結果はSevenElevenモジュールで定義したdrinkとなります。

もちろん、子孫側のメソッド中でsuperを使えば、先祖側の同名メソッドを呼び出せます。

superを呼び出す場所に注意してください。

  • include
    • superを使うのは子孫側 = include「する」側(例ではKagawa3)
  • prepend
    • superを使うのは子孫側 = prepend「される」側(例ではSevenEleven2)

次のページでは実例として、Railsでよく使われるalias_method_chainをprependで書き換えてみます。

  • 前のページへ
  • 1
  • 2
  • 3
  • 次のページへ

あわせて読みたい

あなたにオススメ

    表示について

    カテゴリー一覧

    All Aboutサービス・メディア

    All About公式SNS
    日々の生活や仕事を楽しむための情報を毎日お届けします。
    公式SNS一覧
    © All About, Inc. All rights reserved. 掲載の記事・写真・イラストなど、すべてのコンテンツの無断複写・転載・公衆送信等を禁じます