views:

99

answers:

2

Im trying to do some metaprogramming and would like to know the names of the variables passed as block arguments:

z = 1 # this variable is still local to the block   

Proc.new { |x, y| local_variables }.call

# => ['_', 'z', x', 'y']

I am not quite sure how to differentiate between the variables defined outside the block and the block arguments in this list. Is there any other way to reflect this?

+3  A: 

Here's how you can tell in Ruby 1.8:

>> z = 1
=> 1
>> Proc.new{|x| "z is #{defined? z}, x is #{defined? x}"}.call(1)
=> "z is local-variable, x is local-variable(in-block)"

but, caution! this doesn't work in Ruby 1.9 - you'll get

=> "z is local-variable, x is local-variable"

and I don't know the answer then.

Peter
Thank you, I would have never thought of that.
Corban Brook
+1  A: 

As for a ruby 1.9 solution I am not 100% sure but ruby 1.9.2 is adding a Method#parameters method which returns the params in an array of :symbols

irb(main):001:0> def sample_method(a, b=0, *c, &d);end
=> nil
irb(main):002:0> self.method(:sample_method).parameters
=> [[:req, :a], [:opt, :b], [:rest, :c], [:block, :d]]

Not sure if they have a solution for block parameters as well.

Corban Brook