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.