[英]Unexpected value of __callee__ when including a module – is this a Ruby bug?
通過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
我已將其發布到Ruby Bug Tracker,以試圖激起答案。
更新2
顯然,我不是唯一一個對此問題感到驚訝的人。 我想知道版本50728 (本是用於解決錯誤__callee__
: __callee__
在orphan proc中返回錯誤的方法名稱 )是否可能相關。
您可以在Ruby的Kernel模塊中看到__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__
尋找與__callee__
調用最接近的被調用方法的ID。 在eval.c
的848至906行中可以更好地看出這一點:在類似於<something> -> called_id
與<something> -> def->original_id
<something> -> called_id
的返回調用上查找兩種方法的差異。
另外,如果您從1.9.3版開始查看內核,您會發現兩個方法最初是相同的。 因此,在某些時候,兩者之間有目的性的變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.