【问题标题】:Is JRuby's implementation of Kernel#__method__ broken?JRuby 的 Kernel#__method__ 实现是否损坏?
【发布时间】:2015-01-14 00:03:18
【问题描述】:

这是Kernel#__method__according to Ruby-Doc.org的描述(强调):

返回名称当前方法的定义作为符号。如果在方法外调用,则返回nil

现在考虑以下代码 sn-p:

DEFINITION = proc { __method__ }

class C
  define_method :one, DEFINITION
  define_method :two, DEFINITION
end

o = C.new

当我使用 MRI v1.8.7+ 运行以下命令时,我得到了预期的结果:

o.one  #=> :one
o.two  #=> :two

但是,当我使用 JRuby 1.7+ 运行相同的代码时(我还没有测试过以前的版本):

o.one  #=> :two
o.two  #=> :two

这是否可以被认为是 JRuby 实现中的缺陷,还是仅仅是对 Kernel#__method__ 的不同解释?

【问题讨论】:

  • 查看运行 DEFINITION.call 时两种情况下会发生什么。
  • 在这两种情况下,返回值都是:two
  • 也许,只需将其报告为 JRuby(兼容性)错误 ...

标签: ruby jruby defects


【解决方案1】:

可能是JRuby对__method__的实现有缺陷,也可能是define_method的实现有bug,也可能是严格限制了两者一起使用。看看如果使用& 运算符将Proc 对象转换为块会发生什么:

DEFINITION = proc { __method__ }

class C
  define_method :one, &DEFINITION
  define_method :two, &DEFINITION
end

o = C.new

现在在 MRI 中,和以前一样:

o.one  #=> :one
o.two  #=> :two

但是,在 JRuby 中,它是固定的:

o.one  #=> :one
o.two  #=> :two

鉴于 MRI 的 define_method 的内部实现,包括处理 Proc 参数与块参数,如果 JRuby 完全相似,那么问题可能出在这。

无论哪种方式,将__method__ 替换为selfbindingobject_id 或它们的任何组合或排列都找不到相似之处,因此该问题肯定局限于@987654336 的使用@。

更新:扭曲结局

This was a known bug in MRI 1.9.2,JRuby 的实现反映了这种行为。

【讨论】:

  • 返回值的差异取决于 proc 是否被转换为代码块,这似乎证实了这确实是一个错误。我开了一张票here
猜你喜欢
  • 1970-01-01
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
相关资源
最近更新 更多