Получить имя исполняемого в данный момент метода

198

$0 переменная для программы Ruby верхнего уровня, но есть ли она для текущего метода?

salt.racer
источник
Одно из применений: проверка superможет быть вызвана внутри объекта SimpleDelegator:def description; __getobj__.respond_to?(__method__) ? super : 'No description'; end
Kris

Ответы:

334

Даже лучше, чем мой первый ответ, вы можете использовать __method__:

class Foo
  def test_method
    __method__
  end
end

Это возвращает символ - например :test_method,. Чтобы вернуть имя метода в виде строки, вызовите __method__.to_sвместо этого.

Примечание: для этого требуется Ruby 1.8.7.

Марк А. Николози
источник
11
«:» это просто символ символа. :) Просто сделайте, __method__.to_sи это будет имя метода, ничего больше
Lambart
Что если я нахожусь в грабли?
Имран Ахмад
24

С 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
Это было очень полезно для меня, чтобы найти имя вызывающего (в отличие от текущего) метода.
Ламбарт
Не __callee__делает это?
Джошуа Пинтер
Отличное решение Mark Лучшее решение на данный момент. Отличная работа
Джонатанкаликсто
18

В зависимости от того, что вы на самом деле хотите, вы можете использовать либо, __method__либо __callee__, которые возвращают имя исполняемого метода в качестве символа.

На ruby ​​1.9 они оба ведут себя одинаково (что касается документации и моего тестирования).

На ruby ​​2.1 и 2.2 __callee__ведет себя по-разному, если вы вызываете псевдоним определенного метода. В документах для двух различны:

  • __method__: «имя в определении текущего метода» (т.е. имя в том виде, как оно было определено)
  • __callee__: "вызываемое имя текущего метода" (т.е. имя, как оно было вызвано (вызвано))

Тестовый скрипт:

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 Вывод:

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

2.1.2 Выход ( __callee__возвращает псевдоним, но __method__возвращает имя в точке, где был определен метод):

2.1.2
{:call_orig=>{:callee=>:orig, :method=>:orig},
 :call_alias=>{:callee=>:myalias, :method=>:orig}}
кельвин
источник
10

Для Ruby 1.9+ я бы порекомендовал использовать __callee__

L3x
источник
3
__callee__ведет себя по-разному до 1.9, поэтому лучше придерживаться, __method__поскольку он имеет последовательное поведение. __callee__ведет себя так же, как __method__после 1.9.
Ли МакКаллох
@LeighMcCulloch Можете ли вы объяснить разницу на примере (возможно, в новом ответе)?
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
@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Разве ты не видишь ничего странного?
jgburet
4
@LeighMcCulloch на самом деле сейчас __callee__и __method__имеет другое поведение. Смотрите pastie.org/10380985 (ruby 2.1.5)
goodniceweb
1
pastie.org не работает Навсегда или только сейчас?
Накилон
-3

Я получил ту же проблему, чтобы получить имя метода в файле просмотра. Я получил решение от

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

если вы хотите получить имя контроллера, то

params[:controller] # it will return you controller's name
Хетал Хунти
источник
4
Я думаю, что вы неправильно поняли вопрос о действиях контроллера rails и методах http ... этот ответ, вероятно, следует удалить.
Фактор Мистик
Полезно для получения имени текущего выполняющегося (контроллера) метода из представления.
avjaarsveld