开发者

Is there a way to know the invoking method?

开发者 https://www.devze.com 2022-12-13 05:51 出处:网络
I know the class method tells what is the name of the class of an object, how could I know the name of the invoking method? Is there a开发者_运维百科 way to know that?Examining the Ruby Call Stack sha

I know the class method tells what is the name of the class of an object, how could I know the name of the invoking method? Is there a开发者_运维百科 way to know that?


Examining the Ruby Call Stack shares this information:

Have you ever wanted to look at the call stack without raising an exception to do it?

caller.each {|c| puts c}


caller is a kernal method that lets you do this, so caller[0] will let you know the immediate caller of the function.

a quick hack to get only the name of the function could be

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

this will return the name of the calling method as a String, which you can then use however you want


Ruby's implementation of Kernel#caller was done with Strings for performance and garbage collection reasons. If you want to do more sophisticated call stack analysis, take a look at this blog post:

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

The author goes through two different implementations of a better call stack object graph, one implemented in pure Ruby with the (not widely known) Kernel#set_trace_func method and another that works as a C extension to MRI.

A production application shouldn't use anything other than the Kernel#caller implementation that comes with Ruby. If you use the extensions above extensively you'll probably end up killing Ruby's ability to garbage collect effectively and slow down your process (I estimate) up to several orders of magnitude.


You can write something like this:

module Kernel
  private
  def who_is_calling? # Or maybe def who_just_called?
    caller[1] =~ /`([^']*)'/ and $1
  end
end

And then you have these small tests:

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>
0

精彩评论

暂无评论...
验证码 换一张
取 消