Récupère le nom de la méthode en cours d'exécution


198

$0 est la variable pour le programme Ruby de niveau supérieur, mais y en a-t-il une pour la méthode actuelle?


Une utilisation est la vérification superpeut être appelée dans un objet SimpleDelegator:def description; __getobj__.respond_to?(__method__) ? super : 'No description'; end
Kris

Réponses:


334

Encore mieux que ma première réponse, vous pouvez utiliser __method__:

class Foo
  def test_method
    __method__
  end
end

Cela renvoie un symbole - par exemple :test_method,. Pour renvoyer le nom de la méthode sous forme de chaîne, appelez__method__.to_s place.

Remarque: Cela nécessite Ruby 1.8.7.


11
le ':' est juste le symbole du symbole. :) faites-le __method__.to_set ce sera le nom de la méthode, rien d'autre
Lambart

Et si je suis en râteau?
Imran Ahmad

24

Depuis 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

5
Cela m'a été très utile pour trouver le nom de la méthode appelante (par opposition à la méthode actuelle).
Lambart

Ne fait __callee__pas ça?
Joshua Pinter

Great solution Mark La meilleure solution à l'heure actuelle. Excellent travail
jonathanccalixto

18

Selon ce que vous voulez réellement, vous pouvez utiliser soit __method__ou __callee__, qui renvoient le nom de la méthode en cours d'exécution sous forme de symbole.

Sur ruby ​​1.9, les deux se comportent de manière identique (en ce qui concerne les documents et mes tests).

Sur ruby ​​2.1 et 2.2 __callee__se comporte différemment si vous appelez un alias de la méthode définie. Les documents pour les deux sont différents:

  • __method__: "le nom à la définition de la méthode courante" (ie le nom tel qu'il a été défini)
  • __callee__: "le nom appelé de la méthode courante" (ie le nom tel qu'il a été appelé (invoqué))

Script de test:

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

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

2.1.2 Sortie ( __callee__retourne le nom alias, mais __method__retourne le nom au point où la méthode a été définie):

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

10

Pour Ruby 1.9+, je recommanderais d'utiliser __callee__


3
__callee__se comporte différemment avant la 1.9, il est donc préférable de s'y tenir __method__car il a un comportement cohérent. __callee__se comporte comme __method__après 1.9.
Leigh McCulloch

@LeighMcCulloch pouvez-vous expliquer la différence avec un exemple (éventuellement dans une nouvelle réponse)?
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; m2Ne voyez-vous rien d'étrange?
jgburet

4
@LeighMcCulloch en fait maintenant __callee__et __method__a un comportement différent. Voir pastie.org/10380985 (ruby 2.1.5)
goodniceweb

1
pastie.org est en panne. Pour toujours ou juste maintenant?
Nakilon

-3

J'ai eu le même problème pour récupérer le nom de la méthode dans le fichier de vue. J'ai la solution par

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

si vous voulez obtenir le nom du contrôleur,

params[:controller] # it will return you controller's name

4
Je pense que vous avez mal interprété la question concernant les actions du contrôleur de rails et les méthodes http ... cette réponse devrait probablement être supprimée.
Factor Mystic

Utile pour obtenir le nom de la méthode (contrôleur) en cours d'exécution à partir de la vue.
avjaarsveld
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.