Ruby 2.3+中的对象#方法通过包含的模块的别名表现不同

时间:2017-08-10 16:50:32

标签: ruby

根据建议here我写了一些使用Object#method来测试方法是否正确别名的规范。在某些情况下,该类对来自包含模块的方法进行别名处理。这适用于2.2但不适用于2.3和2.4

我做了一些实验,差异可以归结为:

module Foo
  def foo
  end
  alias_method :foo_foo, :foo
end

class Bar
  include Foo
  alias_method :bar, :foo
end

bar = Bar.new
bar.method(:foo) == bar.method(:bar)
# true in Ruby 2.2
# false in Ruby 2.3+

bar.method(:foo) == bar.method(:foo_foo)
# true in Ruby 2.2+

有人知道这是否是Ruby 2.3中的故意更改?如果是的话,这里发生了什么?

我专门测试了2.2.3,2.2.7,2.3.0,2.3.3,2.3.4和2.4.1。

1 个答案:

答案 0 :(得分:0)

事实证明这是Ruby 2.3的故意改变。

原因是如果所有者不同,Method#==将返回false。来自the bug discussion

  

如果方法的所有者不同,super的行为在方法上是不同的,因此Method#==不应该对方法返回true。

正如mudasobwa所指出的,Method#original_name是这种情况的一个很好的选择。 Method#source_location似乎是另一个强有力的选择。