もふもふ技術部

Rubyのalias_method_chainについて調べた


今回はRuby2系の新機能の検証をしようと思いModule#prependについて調べていたのですが、どうやらそれ以前にalias_method_chainについて知っておく必要がありそうだったので試してみます。

と思いきや、さらにalias_method_chainの先にaliasについて知っておく必要がありそうですね。マトリョーシカ状態です。

環境はMac Book Air, OSX Lionで、rubyはRVMを使っています。

Rubyのalias

例えば、こんな感じにhello worldするためのクラスがあるとします。

hello_world.rb

実行すると当然下記のようになりますね。

Rubyはこのクラスのメソッドを動的に再定義することが出来るという特徴あります。hello_worldメソッド再定義してみます。

alias1.rb

先程と同じようにhello.hello_worldで呼び出したら、hello_world_kusottare!と言われるようになりました。

くそったれ!だなんてお下品ですね!

ところが、上記のようにメソッドをまるっと再定義したい場合はいいんですが、元々のメソッドをちょっと拡張したいっていうような場合もありますよね。

そこでaliasを使います。

こういう感じ。非常にわけがわからないコードになるのですが、こうすることで元のメソッドいかしながら機能を拡張することが出来ます。

呼び出し方が変わることなく、機能だけ拡張することが出来るわけですね。

普通にクラスを継承させても同じようなことは出来そうですが、新たなクラスを作る必要がないのと、柔軟に拡張出来るのが利点なんでしょうか。このあたり言語仕様の恩恵があって、Rubygemsのような便利な仕組みが成り立っているんじゃないかと思います。

alias_method_chain

ところが、このコード、ちょっとわかりづらいしダサいですよね(〜oldとか)。もっとシンプルに記述出来るようになったのが、alias_method_chainです。

先程のコードと同じ挙動するのが下記のコードです。

単純にaliasが2つ必要だったのが、alias_method_chainの1つ片付くようになっているわけです。

ただし注意が必要なのが、拡張したメソッド名は oooo_with_xxxx とし、退避されるメソッド別名は oooo_without_xxxx という命名規則がある点。これに気付かずにちょっとハマったり。

そんな感じでスッキリしました。さらにRuby2系からModule#prependという仕組みが追加されました。本当はそのあたりを調べたかったのですが、まずはその過程を理解していないと何が便利かわからないですからね。

The following two tabs change content below.
原田 敦

原田 敦

日本CAWのエンジニア。もふもふ部の部長。得意分野はRuby on Railsを使った小規模WEBアプリケーションを高速で開発すること。週末の楽しみは一人お菓子パーティー。三度の飯より小動物をもふもふするのが好きです。