Difference between __callee__ and __method__

2020-07-01 07:44发布

In Ruby, one can use either

__callee__ 

or

__method__ 

to find the name of the currently executing method.

What is the difference between the two?

3条回答
Melony?
2楼-- · 2020-07-01 08:24

To paraphrase the documentation, __callee__ is the name of the method that the caller called, whereas __method__ is the name of the method at definition. The following example illustrates the difference:

class Foo

  def foo
    puts __callee__
    puts __method__
  end

  alias_method :bar, :foo
end

If I call Foo.new.foo then the output is

foo
foo

but if I call Foo.new.bar then the output is

bar
foo

__method__ returns :foo in both cases because that is the name of the method as defined (i.e. the class has def foo), but in the second example the name of the method the caller is calling is bar and so __callee__ returns that.

查看更多
祖国的老花朵
3楼-- · 2020-07-01 08:30

__method__ looks up the name statically, it refers to the name of the nearest lexically enclosing method definition. __callee__ looks up the name dynamically, it refers to the name under which the method was called. Neither of the two necessarily needs to correspond to the message that was originally sent:

class << (foo = Object.new)
  def bar(*) return __method__, __callee__ end
  alias_method :baz, :bar
  alias_method :method_missing, :baz
end

foo.bar # => [:bar, :bar]
foo.baz # => [:bar, :baz]
foo.qux # => [:bar, :method_missing]
查看更多
放我归山
4楼-- · 2020-07-01 08:41

__method__ returns defined name, and __callee__ returns called name. They are same usually, but different in a aliased method.

def foo
[__method__, __callee__]
end
alias bar foo
p foo #=> [:foo, :foo]
p bar #=> [:foo, :bar]

link

查看更多
登录 后发表回答