jrichardlai
jrichardlai

Reputation: 3357

How to get the name of the calling method?

is there a way in Ruby to find the calling method name inside of a method?

For example:

class Test
  def self.foo
    Fooz.bar
  end
end

class Fooz
  def self.bar
    # get Test.foo or foo
  end
end

Upvotes: 188

Views: 95671

Answers (8)

Mike Slinn
Mike Slinn

Reputation: 8403

The answer from @amitkarsale works, but private does not do anything in a module since modules are not instantiated. Here is call_chain.rb, rewritten according to Rubocop's suggestions:

module CallChain
  def self.caller_method(depth = 1)
    parse_caller(caller(depth + 1).first).last
  end

  def self.parse_caller(at)
    return unless /^(.+?):(\d+)(?::in `(.*)')?/ =~ at

    file   = Regexp.last_match[1]
    line   = Regexp.last_match[2].to_i
    method = Regexp.last_match[3]
    [file, line, method]
  end
end

if __FILE__ == $PROGRAM_NAME
  caller = CallChain.caller_method
  puts caller
end

Upvotes: 1

Dorian
Dorian

Reputation: 23939

Use caller_locations(1,1)[0].label (for ruby >= 2.0)

Edit: My answer was saying to use __method__ but I was wrong, it returns the current method name.

Upvotes: 40

I use

caller[0][/`([^']*)'/, 1]

Upvotes: 21

Marc-André Lafortune
Marc-André Lafortune

Reputation: 79562

In Ruby 2.0.0, you can use:

caller_locations(1,1)[0].label

It's much faster than the Ruby 1.8+ solution:

caller[0][/`([^']*)'/, 1]

Will get included in backports when I get the time (or a pull request!).

Upvotes: 194

DigitalRoss
DigitalRoss

Reputation: 146073

puts caller[0]

or perhaps...

puts caller[0][/`.*'/][1..-2]

Upvotes: 240

user3769125
user3769125

Reputation: 11

In order to see the caller and callee information in any language, whether it be ruby or java or python, you would always want to look at the stack trace. In some languages, such as Rust and C++, there are options built into the compiler to turn on some sort of profiling mechanism you can view during run time. I do belive one exists for Ruby called ruby-prof.

And as mentioned above, you could look into the execution stack for ruby. This execution stack is an array containing backtrace location objects.

Essentially all you need to know about this command is as follows:

caller(start=1, length=nil) → array or nil

Upvotes: 0

amit karsale
amit karsale

Reputation: 755

Instead you can write it as library function and make a call wherever needed. The code goes as follows :

module CallChain
  def self.caller_method(depth=1)
    parse_caller(caller(depth+1).first).last
  end

  private

  # Copied from ActionMailer
  def self.parse_caller(at)
    if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
      file   = Regexp.last_match[1]
      line   = Regexp.last_match[2].to_i
      method = Regexp.last_match[3]
      [file, line, method]
    end
  end
end

To trigger the above module method you need to call like this: caller = CallChain.caller_method

code reference from

Upvotes: 4

thrice801
thrice801

Reputation: 1671

How about

caller[0].split("`").pop.gsub("'", "")

Much cleaner imo.

Upvotes: 4

Related Questions