我知道class方法可以告诉我们一个对象所属的类名,那么如何知道调用该方法的方法名呢?有没有办法知道这个呢?
Caller是一个内核方法,可以让你做到这一点,因此caller[0]将让你知道函数的直接调用者。
获取函数名称的快速方法可能是一个简单的hack:
caller[0][/`\S+/].chop[1..-1]
这将以字符串形式返回调用方法的名称,您可以随意使用它。
Ruby的Kernel#caller
实现是使用String
来提高性能和垃圾回收效率。如果您想进行更复杂的调用堆栈分析,请参考这篇博客文章:
http://eigenclass.org/hiki/ruby+backtrace+data
作者讲解了两种不同的改进调用栈对象图的实现方式,一种是在纯Ruby中使用(不太常见的)Kernel#set_trace_func
方法实现,另一种则作为C扩展程序运行于MRI中。Kernel#caller
实现之外的任何东西。如果您广泛使用上述扩展程序,可能会导致Ruby无法有效进行垃圾回收并拖慢进程速度(我估计)高达数个数量级。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>