2009-12-07 3 views
6

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

+4

Не то, что это не правильный вопрос, и все, но приходится смотреть на вызов стек обычно означает, что вы делаете что-то неправильно. –

ответ

10

Examining the Ruby Call Stack разделяет эту информацию:

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

caller.each {|c| puts c} 
3

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

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

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

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

1

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

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

Автор проходит через два различных реализаций лучшего вызова графа объекта стека, один реализован в чистом Ruby, с (не широко известный) Kernel#set_trace_func и другой, который работает как расширение C для МРТ.

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

0

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

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>