Obtenga el nombre del método que se está ejecutando actualmente

198

$0 es la variable para el programa Ruby de nivel superior, pero ¿hay alguna para el método actual?

corredor de sal
fuente
Un uso es la comprobación superse puede llamar dentro de un objeto SimpleDelegator:def description; __getobj__.respond_to?(__method__) ? super : 'No description'; end
Kris

Respuestas:

334

Incluso mejor que mi primera respuesta, puede usar __method__:

class Foo
  def test_method
    __method__
  end
end

Esto devuelve un símbolo, por ejemplo :test_method,. Para devolver el nombre del método como una cadena, llame en su __method__.to_slugar.

Nota: Esto requiere Ruby 1.8.7.

Mark A. Nicolosi
fuente
11
el ':' es solo el símbolo del símbolo. :) solo hazlo __method__.to_sy será el nombre del método, nada más
Lambart
¿Qué pasa si estoy en una tarea de rastrillo?
Imran Ahmad
24

De 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
fuente
55
Esto fue muy útil para mí para encontrar el nombre del método de llamada (en oposición al método actual).
Lambart
¿ __callee__No hace esto?
Joshua Pinter
Gran solución Mark La mejor solución en este momento. Gran trabajo
jonathanccalixto
18

Dependiendo de lo que realmente desee, puede usar cualquiera __method__o __callee__, que devuelve el nombre del método que se está ejecutando actualmente como un símbolo.

En ruby ​​1.9, ambos se comportan de manera idéntica (en lo que respecta a los documentos y mis pruebas).

En ruby ​​2.1 y 2.2 se __callee__comporta de manera diferente si llama a un alias del método definido. Los documentos para los dos son diferentes:

  • __method__: "el nombre en la definición del método actual" (es decir, el nombre como se definió)
  • __callee__: "el nombre llamado del método actual" (es decir, el nombre como se llamó (invocado))

Script de prueba:

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

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

2.1.2 Salida ( __callee__devuelve el nombre con alias, pero __method__devuelve el nombre en el punto en que se definió el método):

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

Para Ruby 1.9+, recomendaría usar __callee__

l3x
fuente
3
__callee__se comporta de manera diferente antes de 1.9, por lo que es mejor seguir __method__ya que tiene un comportamiento constante. __callee__se comporta igual que __method__después de 1.9.
Leigh McCulloch
@LeighMcCulloch, ¿puede explicar la diferencia con un ejemplo (posiblemente en una nueva respuesta)?
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; m2¿No ves nada extraño?
jgburet
44
@LeighMcCulloch en realidad ahora __callee__y __method__tiene un comportamiento diferente. Ver pastie.org/10380985 (ruby 2.1.5)
goodniceweb
1
pastie.org está caído. ¿Por siempre o ahora?
Nakilon
-3

Tengo el mismo problema para recuperar el nombre del método en el archivo de vista. Obtuve la solución por

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

si quieres obtener el nombre del controlador, entonces

params[:controller] # it will return you controller's name
Hetal Khunti
fuente
44
Creo que malinterpretaste la pregunta sobre las acciones del controlador de rieles y los métodos http ... esta respuesta probablemente debería eliminarse.
Factor Mystic
Útil para obtener el nombre del método (controlador) actualmente en ejecución desde la vista.
avjaarsveld