Есть ли способ узнать метод вызова? - PullRequest
6 голосов
/ 07 декабря 2009

Я знаю, что метод class сообщает, как называется класс объекта, как я могу узнать имя вызывающего метода? Есть ли способ узнать это?

Ответы [ 4 ]

10 голосов
/ 07 декабря 2009

Изучение стека вызовов Ruby делится этой информацией:

Вы когда-нибудь хотели посмотреть на стек вызовов, не вызывая исключения для этого?

caller.each {|c| puts c}
3 голосов
/ 07 декабря 2009

caller - это метод kernal, который позволяет вам делать это, поэтому caller [0] сообщит вам о непосредственном вызове функции.

быстрый взлом, чтобы получить только имя функции может быть

caller[0][/`\S+/].chop[1..-1]

это вернет имя вызывающего метода в виде строки, которую вы можете затем использовать по своему усмотрению

1 голос
/ 07 декабря 2009

Реализация Kernel#caller в Ruby была сделана с String s для повышения производительности и сбора мусора. Если вы хотите сделать более сложный анализ стека вызовов, посмотрите на это сообщение в блоге:

http://eigenclass.org/hiki/ruby+backtrace+data

Автор рассматривает две различные реализации лучшего графа объектов стека вызовов, одна реализована в чистом Ruby с помощью (не широко известного) метода Kernel#set_trace_func, а другая работает как расширение C для MRI.

Производственное приложение не должно использовать ничего, кроме реализации Kernel#caller, которая поставляется с Ruby. Если вы будете широко использовать вышеупомянутые расширения, вы, вероятно, в конечном итоге убьете способность Руби эффективно собирать мусор и замедлять ваш процесс (я оцениваю) до нескольких порядков.

0 голосов
/ 08 декабря 2009

Вы можете написать что-то вроде этого:

module Kernel
  private
  def who_is_calling? # Or maybe def who_just_called?
    caller[1] =~ /`([^']*)'/ and $1
  end
end

А потом у вас есть эти маленькие тесты:

irb(main):056:0*   def this_is_a_method
irb(main):057:1>     puts "I, 'this_is_a_method', was called upon by: '#{who_is_calling?}'"
irb(main):058:1>   end
=> nil
irb(main):059:0>   def this_is_a_method_that_calls_another
irb(main):060:1>     this_is_a_method
irb(main):061:1>   end
=> nil
irb(main):062:0> this_is_a_method_that_calls_another
I, 'this_is_a_method', was called upon by: 'this_is_a_method_that_calls_another'
=> nil
irb(main):063:0> this_is_a_method
I, 'this_is_a_method', was called upon by: 'irb_binding'
=> nil
irb(main):064:0>
...