1

这是Kernel#__method__ 根据 Ruby-Doc.org的描述(强调添加):

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

现在考虑以下代码片段:

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__?

4

1 回答 1

4

可能是 JRuby 实现的缺陷__method__,也可能是实现的 bug define_method,也可能严格限制为两者一起使用。看看如果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或它们的任何组合或排列来找到相似之处,因此问题肯定局限于__method__.

更新:扭曲结局

这是 MRI 1.9.2 中的一个已知错误,JRuby 的实现反映了这种行为。

于 2014-11-17T08:32:44.233 回答