【问题标题】:Is there a way to know the invoking method?有没有办法知道调用方法?
【发布时间】:2010-12-24 00:25:01
【问题描述】:

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

【问题讨论】:

  • 并不是说这不是一个有效的问题,而是必须查看调用堆栈通常意味着您做错了什么。

标签: ruby callstack


【解决方案1】:

你可以这样写:

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>

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

        Examining the Ruby Call Stack 分享此信息:

        您是否曾经想在不引发异常的情况下查看调用堆栈?

        caller.each {|c| puts c}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-05-10
          • 2012-02-17
          • 2019-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-20
          相关资源
          最近更新 更多