When invoked via a method created by alias_method
, __callee__
ignores the name of the old method (here xxx
) and returns the name of the new method, as below:
class Foo
def xxx() __callee__ end
alias_method :foo, :xxx
end
Foo.new.foo # => :foo
This behavior holds even when xxx
is inherited from a superclass:
class Sup
def xxx() __callee__ end
end
class Bar < Sup
alias_method :bar, :xxx
end
Bar.new.bar # => :bar
Given both of the above, I would expect that the same behavior would hold when xxx
is included via a module. However, that is not the case:
module Mod
def xxx() __callee__ end
end
class Baz
include Mod
alias_method :baz, :xxx
end
Baz.new.baz # => :xxx
I expect the return value to be :baz
, not :xxx
.
The above code was executed using Ruby 2.3.1p112. Is this a bug in the implementation of __callee__
? Or maybe of alias_method
? And if not, can anyone explain why module inclusion behaves differently?
UPDATE 1
I've posted this to the Ruby bug tracker to try to stir up an answer.
UPDATE 2
Apparently, I'm not the only one to be surprised by this issue. I wonder whether Revision 50728 (which was meant to solve Bug 11046: __callee__
returns incorrect method name in orphan proc) might be related.
You can see the difference between __callee__
and __method__
in Ruby's Kernel module.
The difference is the calls prev_frame_callee()
and prev_frame_func()
, respectively. I found these function definitions at http://rxr.whitequark.org/mri/source/eval.c
In short, Foo and Bar are immediately calling the aliased methods foo and bar (which are names for xxx), while Baz has to find Mod and call xxx from Mod. __method__
looks for the original called method's id, while __callee__
looks for the closest called method's id to the __callee__
call. This is better seen in eval.c
at lines 848 to 906: look for the difference in the two methods on the return calls similar to <something> -> called_id
vs <something> -> def->original_id
.
Also, if you look at the Kernel from version 1.9.3, you will see that the two methods originally were the same. So, at some point, there was a purposeful change between the two.
This was a bug, and it was closed 3 days ago with this note:
Seems fixed by r56592.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With