0

I want a method to be used within another method and returns the arguments without the need of mentioning the argument names, something like return_arguments in the following.

def foo a, b, *c
  ... # part a
  p return_arguments
  ... # part b
end

foo(1, "blah blah", :a, :b)
... # return from part a
# => [1, "blah blah", :a, :b]
... # return from part b

Is this possible? I figured out that binding, local_variables, and eval may be used, but am not sure how to distinguish the arguments from other local variables defined in part a above. Is there a particular ordering rule for local_variables? If so, maybe I can use that together with arity to extract the arguments.

sawa
  • 165,429
  • 45
  • 277
  • 381
  • This is a very peculiar sort of thing to be doing. You'd be better off passing in a hash with named arguments if you're able to do that instead. – tadman Oct 01 '12 at 02:49

3 Answers3

1

Use local_variables first thing in the method, i.e. before setting any local variables, and save the result for later use.

muratgu
  • 7,241
  • 3
  • 24
  • 26
1

Probably the easiest thing to do would be something like this:

def foo(*args)
  a, b, *c = *args
  # (...)
  p args
  # (...)
end

Or conversely:

def foo(a, b, *c)
  args = [a, b, *c]
  # (...)
  p args
  # (...)
end

I'm not sure why you are opposed to mentioning the argument names at least once. It's most straightforward and readable to either assign your "arguments" inside your method (letting to keep the full array) or to reconstruct the array from the parsed arguments.

Jeremy Roman
  • 16,137
  • 1
  • 43
  • 44
  • I am not opposing to use the argument names at all. I am just opposing to use it when I call `return_arguments`. – sawa Sep 30 '12 at 19:50
1

It's definitely inefficient, but here's a solution (although you probably should be using a hash like @tadman mentioned):

set_trace_func proc { |e,_,_,i,b,_|
   if e == 'call'
      p = method(i).parameters
      @arguments = p.map {|p| eval(p[1].to_s,b)}
   end
}

def foo a, b, *c
   a = 50
   b = 3
   return @arguments
   a = 11
   b = 2
end

p foo(1, "blah blah", :a, :b)
Josh Voigts
  • 4,114
  • 1
  • 18
  • 43