【发布时间】:2010-12-24 00:25:01
【问题描述】:
我知道类方法告诉对象类的名称是什么,我怎么知道调用方法的名称?有办法知道吗?
【问题讨论】:
-
并不是说这不是一个有效的问题,而是必须查看调用堆栈通常意味着您做错了什么。
我知道类方法告诉对象类的名称是什么,我怎么知道调用方法的名称?有办法知道吗?
【问题讨论】:
你可以这样写:
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>
【讨论】:
出于性能和垃圾收集的原因,Ruby 对Kernel#caller 的实现是使用Strings 完成的。如果您想进行更复杂的调用堆栈分析,请查看这篇博文:
http://eigenclass.org/hiki/ruby+backtrace+data
作者介绍了更好的调用堆栈对象图的两种不同实现,一种在纯 Ruby 中使用(不广为人知的)Kernel#set_trace_func 方法实现,另一种作为 MRI 的 C 扩展。
生产应用程序不应使用除 Ruby 附带的 Kernel#caller 实现之外的任何东西。如果您广泛使用上述扩展,您可能最终会扼杀 Ruby 有效垃圾收集的能力,并将您的进程(我估计)减慢几个数量级。
【讨论】:
caller 是一个内核方法,可让您执行此操作,因此 caller[0] 将让您知道该函数的直接调用者。
快速获取函数名称的方法可能是
caller[0][/`\S+/].chop[1..-1]
这会将调用方法的名称作为字符串返回,然后您可以随意使用它
【讨论】:
【讨论】: