6

我知道类方法告诉对象类的名称是什么,我怎么知道调用方法的名称?有办法知道吗?

4

4 回答 4

10

检查 Ruby 调用堆栈共享以下信息:

你有没有想过在不引发异常的情况下查看调用堆栈?

caller.each {|c| puts c}
于 2009-12-07T13:33:48.943 回答
3

caller 是一个内核方法,可让您执行此操作,因此 caller[0] 将让您知道该函数的直接调用者。

快速获取函数名称的方法可能是

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

这会将调用方法的名称作为字符串返回,然后您可以根据需要使用它

于 2009-12-07T19:13:58.047 回答
1

出于性能和垃圾收集的原因,Ruby 的 s 实现Kernel#caller是用s 完成的。String如果您想进行更复杂的调用堆栈分析,请查看此博客文章:

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

作者介绍了更好的调用堆栈对象图的两种不同实现,一种是在纯 Ruby 中使用(不广为人知的)Kernel#set_trace_func方法实现的,另一种是作为 MRI 的 C 扩展。

生产应用程序不应该使用除了Kernel#callerRuby 附带的实现之外的任何东西。如果您广泛使用上述扩展,您可能最终会扼杀 Ruby 有效垃圾收集的能力,并将您的进程(我估计)减慢几个数量级。

于 2009-12-07T20:44:15.760 回答
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>
于 2009-12-08T08:27:40.860 回答