问题
This is the description of Kernel#__method__
according to Ruby-Doc.org (emphasis added):
Returns the name at the definition of the current method as a Symbol. If called outside of a method, it returns
nil
.
Now consider the following code snippet:
DEFINITION = proc { __method__ }
class C
define_method :one, DEFINITION
define_method :two, DEFINITION
end
o = C.new
When I run the following using MRI v1.8.7+ I'm getting the expected results:
o.one #=> :one
o.two #=> :two
However when I run the same code using JRuby 1.7+ (I haven't tested the previous versions):
o.one #=> :two
o.two #=> :two
Could this be considered a defect in JRuby's implementation or is it simply a different interpretation of Kernel#__method__
?
回答1:
It may be a defect in JRuby's implementation of __method__
, or it may be a bug in the implementation of define_method
, or it may be strictly limited to the use of the two together. Look what happens if you cast the Proc
object into a block by using the &
operator:
DEFINITION = proc { __method__ }
class C
define_method :one, &DEFINITION
define_method :two, &DEFINITION
end
o = C.new
Now in MRI, as before:
o.one #=> :one
o.two #=> :two
However, in JRuby, it's fixed:
o.one #=> :one
o.two #=> :two
Given the internal implementation of MRI's define_method
, which includes the handling of Proc
arguments vs block arguments, if JRuby's is at all similar, it's also possible that that is where the problem could lie.
Either way, there are no parallels to be found by replacing __method__
with self
, binding
, object_id
, or any combination or permutation of them, so the issue is certainly localized to uses of __method__
.
UPDATE: Twist Ending
This was a known bug in MRI 1.9.2, and JRuby's implementation mirrors that behavior.
来源:https://stackoverflow.com/questions/26966547/is-jrubys-implementation-of-kernel-method-broken