2016-02-14 12 views

Odpowiedz

12

__method__ wyszukuje nazwę statycznie, to odnosi się do nazwy najbliższego leksykalnie zamykającym definicji metody. __callee__ dynamicznie wyszukuje nazwę, odnosi się do nazwy, pod którą wywołano tę metodę. Ani z dwóch niekoniecznie musi odpowiadać na wiadomość, która była pierwotniewysłania:

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

Parafrazując documentation, __callee__ jest nazwą metody wywoływanej przez wywołującego, natomiast __method__ jest nazwą metody w definicji. Poniższy przykład ilustruje różnicę:

class Foo 

    def foo 
    puts __callee__ 
    puts __method__ 
    end 

    alias_method :bar, :foo 
end 

Jeśli wywołać Foo.new.foo to wyjście jest

foo 
foo 

ale jeśli wywołać Foo.new.bar to wyjście jest

bar 
foo 

__method__ powraca :foo zarówno przypadki, ponieważ jest to nazwa zdefiniowanej metody (tj. klasa ma def foo), ale w drugim przykładzie nazwa metody wywoływanej przez wywołującego to bar, a więc __callee__ zwraca to.

+0

I nie był świadomy alias_method, więc chyba że użyto oni zawsze zwraca tę samą wartość? – ardochhigh

+2

Myślę, że aliasing (przez alias lub alias_method) jest jedynym czasem, kiedy mogą być różne. –

5

__method__ powraca zdefiniowane nazwy, a __callee__ powraca zwane imię. Są one zwykle takie same, ale różne w metodzie aliasowej.

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

link