加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

包含模块时__callee__的意外值 – 这是Ruby的错误?

发布时间:2020-12-16 19:34:09 所属栏目:百科 来源:网络整理
导读:当通过alias_method创建的方法调用时,__callee__将忽略旧方法的名称(这里为xxx),并返回新方法的名称,如下所示: class Foo def xxx() __callee__ end alias_method :foo,:xxxendFoo.new.foo # = :foo 即使xxx从一个超类继承,这种行为也是一样的: class Sup
当通过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

我有posted this to the Ruby bug tracker尝试挑起一个答案.

更新2

显然,我是not the only one对这个问题感到惊讶.我想知道Revision 50728(这是为了解决Bug 11046: __callee__ returns incorrect method name in orphan proc)可能是相关的.

解决方法

您可以在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__查找__callee__调用中最近调用的方法的id.在第848到906行的eval.c中更好地看到:在类似于< something>的返回调用上查找两个方法的区别. – > called_id对< something> – > def-> original_id.

另外,如果从1.9.3版本看内核,你会发现这两个方法最初是一样的.所以,在某些时候,两者之间有一个有意义的变化.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读