Uzyskaj nazwę aktualnie wykonywanej metody

198

$0 jest zmienną dla programu Ruby najwyższego poziomu, ale czy jest taka dla bieżącej metody?

salt.racer
źródło
Jednym z zastosowań jest sprawdzanie, które supermożna wywołać w obiekcie SimpleDelegator:def description; __getobj__.respond_to?(__method__) ? super : 'No description'; end
Kris,

Odpowiedzi:

334

Nawet lepiej niż moja pierwsza odpowiedź możesz użyć __method__:

class Foo
  def test_method
    __method__
  end
end

Zwraca symbol - na przykład :test_method. Aby zwrócić nazwę metody jako ciąg, wywołaj __method__.to_szamiast niej.

Uwaga: Wymaga to Ruby 1.8.7.

Mark A. Nicolosi
źródło
11
„:” jest tylko symbolem symbolu. :) po prostu zrób, __method__.to_sa będzie to nazwa metody, nic więcej
Lambart
Co się stanie, jeśli wykonam zadanie rake?
Imran Ahmad
24

Od http://snippets.dzone.com/posts/show/2785 :

module Kernel
private
    def this_method_name
      caller[0] =~ /`([^']*)'/ and $1
    end
end

class Foo
  def test_method
    this_method_name
  end
end

puts Foo.new.test_method    # => test_method
Mark A. Nicolosi
źródło
5
Pomogło mi to znaleźć nazwę metody wywołującej (w przeciwieństwie do obecnej).
Lambart
Nie __callee__robi tego?
Joshua Pinter
Świetne rozwiązanie Oznacz teraz Najlepsze rozwiązanie. Świetna robota
jonathanccalixto,
18

W zależności od tego, czego naprawdę chcesz, możesz użyć albo, __method__albo __callee__, który zwraca nazwę aktualnie wykonywanej metody jako symbol.

Na Ruby 1.9 oba zachowują się identycznie (w odniesieniu do dokumentacji i moich testów).

W Ruby 2.1 i 2.2 __callee__zachowuje się inaczej, jeśli wywołasz alias zdefiniowanej metody. W docs dla obu są różne:

  • __method__: „nazwa w definicji bieżącej metody” (tj. nazwa w takiej postaci, w jakiej została zdefiniowana)
  • __callee__: „nazwa wywoływana bieżącej metody” (tj. nazwa, w jakiej została wywołana (wywołana))

Skrypt testowy:

require 'pp'
puts RUBY_VERSION
class Foo
  def orig
    {callee: __callee__, method: __method__}
  end
  alias_method :myalias, :orig
end
pp( {call_orig: Foo.new.orig, call_alias: Foo.new.myalias} )

1.9.3 Wyjście:

1.9.3
{:call_orig=>{:callee=>:orig, :method=>:orig},
 :call_alias=>{:callee=>:orig, :method=>:orig}}

2.1.2 Dane wyjściowe ( __callee__zwraca nazwę aliasu, ale __method__zwraca nazwę w punkcie, w którym metoda została zdefiniowana):

2.1.2
{:call_orig=>{:callee=>:orig, :method=>:orig},
 :call_alias=>{:callee=>:myalias, :method=>:orig}}
kelwin
źródło
10

Dla Ruby 1.9+ polecam używać __callee__

l3x
źródło
3
__callee__zachowuje się inaczej przed wersją 1.9, więc najlepiej trzymać się tego, __method__ponieważ ma spójne zachowanie. __callee__zachowuje się tak samo jak __method__po wersji 1.9.
Leigh McCulloch,
@LeighMcCulloch, czy możesz wyjaśnić różnicę na przykładzie (być może w nowej odpowiedzi)?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@CiroSantilli 六四 事件 法轮功 纳米比亚 威 视def m1() puts("here is #{__method__} method. My caller is #{__callee__}.") end; def m2() puts("here is #{__method__} method. Let's call m1"); m1 end; m2Nie widzisz nic dziwnego?
jgburet
4
@LeighMcCulloch faktycznie teraz __callee__i __method__ma inne zachowanie. Zobacz pastie.org/10380985 (ruby 2.1.5)
goodniceweb
1
pastie.org nie działa. Na zawsze czy tylko teraz?
Nakilon
-3

Mam ten sam problem z pobraniem nazwy metody w pliku widoku. Mam rozwiązanie przez

params[:action] # it will return method's name

jeśli chcesz uzyskać nazwę kontrolera, to

params[:controller] # it will return you controller's name
Hetal Khunti
źródło
4
Myślę, że źle zinterpretowałeś pytanie dotyczące działań kontrolera szyn i metod http ... ta odpowiedź powinna prawdopodobnie zostać usunięta.
Factor Mystic
Przydatne do uzyskania nazwy aktualnie wykonywanej metody (kontrolera) z widoku.
avjaarsveld