thehoooplehead thehoooplehead - 1 year ago 79
Ruby Question

Accessing Calling Scope in Module Method

I'm making a little debug tool to get the arguments passed into a method as follows:

Class bar
def foo(a,b,c)
### do stuff

module Debug
def get_arguments
method(__method__) { |arg| [arg[1],eval(arg[1].to_s)] }.to_h

Currently, it returns and empty hash '{}' while I'd like it to return {a: x, b: y, c: z} (the arguments of foo along with the values).

Is there something like __calling_method__ or __parent_method__? Otherwise, I'd have to put this debugging code in every method.

Answer Source

You can get this done by using eval to evaluate a string of code in the current scope.

Note that there were some errors with your code that I've fixed:

  • in Class bar, the capitalization was wrong
  • you're calling Debug.get_arguments, so get_arguments should be a class method

Note that I'm loading awesome_print just to show the output more clearly; the code is not dependent on it.

The script (test.rb):

require 'awesome_print'

class Bar
  def foo(a,b,c)
    eval Debug.get_arguments

module Debug
  def self.get_arguments
    "method(__method__) { |arg| [arg[1],eval(arg[1].to_s)] }.to_h"

ap 1,2,3

Calling the script:

$ ruby test.rb


    :a => 1,
    :b => 2,
    :c => 3

This shows that eval works even when nested, which is cool.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download