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?


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.


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

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}}

10

Para Ruby 1.9+, recomendaría usar __callee__


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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.