Ir para conteúdo principal
Lucas Caton

[Ruby] How to get the name of the calling method?

Lucas Caton

Lucas Caton

@lucascaton
I was about to run a rake task which would make important changes in my database. My code was similar to this:
ruby
def migrate_active_accounts
  accounts = Account.active
  # Code to migrate accounts here...
end

def migrate_inactive_accounts
  accounts = Account.inactive
  # Code to migrate accounts here...
end
This migration was very critical. Thus, I decided to log everything to make sure it would run as expected. So I wrote a separate method to log what accounts were going to run by which method.
In order to do that, I'd need to know which method was calling my logger method.
I ended up finding the answer on StackOverflow (where else would I?
).

Solution

As usual, Ruby has a neat solution for it: Kernel module has a caller_locations method, which returns an array with the current execution stack. So all we need to do is to use caller_locations.first.label to get the first element from the stack and then get its label.
My final code was looking like the following:
ruby
def migrate_active_accounts
  accounts = Account.active
  log_migration_info(accounts)

  # Code to migrate accounts here...
end

def migrate_inactive_accounts
  accounts = Account.inactive
  log_migration_info(accounts)

  # Code to migrate accounts here...
end

private

def log_migration_info(accounts)
  caller_method = caller_locations.first.label

  Rails.logger.info "Running [MyClass##{caller_method}]
    for the following accounts: #{accounts.map(&:id).to_sentence}"
end

Ruby prior to 2.0

If you're using an old version of Ruby (even though you shouldn't), you'll need to use caller method along with a regular expression:
ruby
caller.first[/`(.*)'/, 1]
Happy hacking!

Post atualizado em 02/10/2017, 10:00:00