当通过alias_method
创建的方法调用时,__callee__
忽略旧方法的名称(此处为xxx
)并返回新方法的名称,如下所示:
class Foo
def xxx() __callee__ end
alias_method :foo, :xxx
end
Foo.new.foo # => :foo
即使从超类继承xxx
,此行为仍然存在:
class Sup
def xxx() __callee__ end
end
class Bar < Sup
alias_method :bar, :xxx
end
Bar.new.bar # => :bar
鉴于上述两种情况,我希望通过模块包含xxx
时,相同的行为将成立。但事实并非如此:
module Mod
def xxx() __callee__ end
end
class Baz
include Mod
alias_method :baz, :xxx
end
Baz.new.baz # => :xxx
我希望返回值为:baz
,而不是:xxx
。
上面的代码是使用Ruby 2.3.1p112执行的。这是__callee__
实施中的错误吗?或许alias_method
?如果没有,任何人都可以解释为什么模块包含行为不同吗?
更新1
我apache commons beanutils试图挑起答案。
更新2
显然,我posted this to the Ruby bug tracker对这个问题感到惊讶。我想知道not the only one(意图解决Revision 50728)是否可能是相关的。
答案 0 :(得分:2)
您可以在Ruby的内核模块中看到__callee__
和__method__
之间的区别。
区别在于调用prev_frame_callee()
和prev_frame_func()
。我在http://rxr.whitequark.org/mri/source/eval.c
简而言之,Foo和Bar会立即调用别名方法foo和bar(它们是xxx的名称),而Baz必须找到Mod并从Mod调用xxx。 __method__
查找原始调用方法的id,而__callee__
查找最近调用方法的id __callee__
调用。在eval.c
第848行到第906行中可以更好地看到这一点:在<something> -> called_id
与<something> -> def->original_id
类似的返回调用中查找两种方法的区别。
另外,如果从版本1.9.3查看内核,您将看到两个方法最初是相同的。所以,在某些时候,两者之间有了一个有目的的变化。
答案 1 :(得分:1)
这是一个错误,它在3天前被关闭with this note:
似乎由r56592确定。