用途

Ruby版EventEmitterなどのincludeして既存クラスを拡張するタイプのライブラリを使う時に、mix-inされる関数と自分の関数の名前が衝突してしまう場合に有用。

Ruby用のsocket.io実装を作っているんだけど、EventEmitter gemで定義されているemit関数を__emitに退避してemitを新たに自分で定義するのに使った。


alias_methodで関数名の衝突を回避する

module Fooをclass Barにincludeした時に、FooにもBarにも同じ関数を定義している場合、クラスの方に定義した関数の方が優先される。
モジュールの方の、せっかくincludeでmix-inした関数は消滅してしまう

includeしたmoduleの方の関数fooも使いたい場合、includeしてすぐにalias_methodで別名に退避するとよい。

module Foo
def foo
puts "foo called!!"
end
end

class Bar
include Foo
alias_method :__foo, :foo ## fooを別名(__foo)に退避

def bar
puts "bar called!!"
end

def foo
puts "Bar's foo called.."
end
end


bar = Bar.new
bar.bar
bar.__foo # include後に退避したmoduleの関数が呼ばれる
bar.foo # include後に上書きした関数が呼ばれる


結果
bar called!!
foo called!!
Bar's foo called..


alias_methodのタイミング

関数の上書き定義後にalias_methodを使っても、退避できない。

module Foo
def foo
puts "foo called!!"
end
end

class Bar
include Foo

def bar
puts "bar called!!"
end

def foo
puts "Bar's foo called.."
end

alias_method :__foo, :foo ## 上書き定義した後にエイリアスでの退避を試みる
end


bar = Bar.new
bar.bar
bar.__foo
bar.foo

fooも__fooも、どちらも上書き定義されたメソッドが呼ばれる。
bar called!!
Bar's foo called..
Bar's foo called..

ちなみにもちろんinclude前にalias_methodしても、NameError(undefined method)例外が起こる。