Rufen Sie den Namen der aktuell ausgeführten Methode ab

198

$0 ist die Variable für das Ruby-Programm der obersten Ebene, aber gibt es eine für die aktuelle Methode?

salt.racer
quelle
Eine Verwendung ist die Überprüfung superkann innerhalb eines SimpleDelegator-Objekts aufgerufen werden:def description; __getobj__.respond_to?(__method__) ? super : 'No description'; end
Kris

Antworten:

334

Noch besser als meine erste Antwort können Sie __method__ verwenden:

class Foo
  def test_method
    __method__
  end
end

Dies gibt ein Symbol zurück - zum Beispiel :test_method. Rufen Sie __method__.to_sstattdessen auf, um den Methodennamen als Zeichenfolge zurückzugeben .

Hinweis: Dies erfordert Ruby 1.8.7.

Mark A. Nicolosi
quelle
11
Das ':' ist nur das Symbol. :) Tu es einfach __method__.to_sund es wird der Methodenname sein, sonst nichts
Lambart
Was ist, wenn ich eine Rechenaufgabe habe?
Imran Ahmad
24

Von 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
quelle
5
Dies war sehr hilfreich für mich, um den Namen der aufrufenden (im Gegensatz zur aktuellen) Methode zu finden.
Lambart
Tut das __callee__nicht?
Joshua Pinter
Tolle Lösung Mark Die derzeit beste Lösung. Großartige Arbeit
Jonathanccalixto
18

Je nachdem, was Sie tatsächlich möchten, können Sie entweder __method__oder verwenden __callee__, die den Namen der aktuell ausgeführten Methode als Symbol zurückgeben.

In Ruby 1.9 verhalten sich beide identisch ( in Bezug auf die Dokumente und meine Tests).

In Ruby 2.1 und 2.2 __callee__verhält es sich anders, wenn Sie einen Alias ​​der definierten Methode aufrufen. Die Dokumente für die beiden sind unterschiedlich:

  • __method__: "der Name bei der Definition der aktuellen Methode" (dh der Name, wie er definiert wurde)
  • __callee__: "der aufgerufene Name der aktuellen Methode" (dh der Name, wie er aufgerufen wurde (aufgerufen))

Testskript:

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 Ausgabe:

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

2.1.2 Ausgabe ( __callee__gibt den Aliasnamen zurück, gibt jedoch __method__den Namen an dem Punkt zurück, an dem die Methode definiert wurde):

2.1.2
{:call_orig=>{:callee=>:orig, :method=>:orig},
 :call_alias=>{:callee=>:myalias, :method=>:orig}}
Kelvin
quelle
10

Für Ruby 1.9+ würde ich die Verwendung empfehlen __callee__

l3x
quelle
3
__callee__verhält sich vor 1.9 anders, daher ist es am besten, sich daran zu halten, __method__da es ein konsistentes Verhalten aufweist. __callee__verhält sich genauso wie __method__nach 1.9.
Leigh McCulloch
@LeighMcCulloch können Sie den Unterschied anhand eines Beispiels erklären (möglicherweise in einer neuen Antwort)?
Ciro Santilli 法轮功 冠状 病. 事件 11
@CiroSantilli see 事件 法轮功 纳米比亚 纳米比亚 威 Siehst 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; m2du nichts Seltsames?
jgburet
4
@LeighMcCulloch eigentlich jetzt __callee__und __method__hat anderes Verhalten. Siehe pastie.org/10380985 (Ruby 2.1.5)
Goodniceweb
1
pastie.org ist ausgefallen. Für immer oder gerade jetzt?
Nakilon
-3

Ich habe das gleiche Problem beim Abrufen des Methodennamens in der Ansichtsdatei. Ich habe die Lösung von bekommen

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

Wenn Sie den Namen des Controllers erhalten möchten, dann

params[:controller] # it will return you controller's name
Hetal Khunti
quelle
4
Ich denke, Sie haben die Frage zu Rails-Controller-Aktionen und http-Methoden falsch interpretiert. Diese Antwort sollte wahrscheinlich gelöscht werden.
Faktor Mystic
Nützlich, um den Namen der aktuell ausgeführten (Controller-) Methode aus der Ansicht abzurufen.
Avjaarsveld