像这样一段代码:
require 'rubygems'
require 'active_support/all'
module A
def f
puts 'this is a'
end
end
module B
def f
puts 'this is b'
super
end
end
class C
include A
include B
end
puts '** test 1, no hacking'
C.new.f
module A
def f_with_test_a
puts 'in HackingA'
f_without_test_a
puts 'out HackingA'
end
alias_method_chain :f, :test_a
end
puts '** test 2, hacking A'
C.new.f
module B
def f_with_test_b
puts 'in HackingB'
f_without_test_b
puts 'out HackingB'
end
alias_method_chain :f, :test_b
end
puts '** test 3, hacking both A & B'
C.new.f
这段代码测试 Ruby 在两层 alias_method 下的情况,这里创建了两个 module,并且用一个类去 include 它们,测试就是对两个 module 的同名方法分别做 alias_method 的 hack,看看是否确实能执行正常。
Ruby 1.9 中执行结果:
** test 1, no hacking
this is b
this is a
** test 2, hacking A
this is b
in HackingA
this is a
out HackingA
** test 3, hacking both A & B
in HackingB
this is b
in HackingA
this is a
out HackingA
out HackingB
可以看到结果是正确的
而 Ruby 1.8 下却是:
** test 1, no hacking
this is b
this is a
** test 2, hacking A
this is b
in HackingA
this is a
out HackingA
** test 3, hacking both A & B
in HackingB
this is b
1.rb:13:in `f_without_test_b': super: no superclass method `f' for #<C:0x10e5aaeb0> (NoMethodError)
from 1.rb:41:in `f'
from 1.rb:49
可以看到在 module B 执行到 super 的时候找不到祖先的 f 方法。。。