Reflection of method parameters in Ruby

Take the following class:

class Automator def fill_specific_form(fields) fields.each_pair do |key, value| puts "Setting '#{key}' to '#{value}'" end end end a = Automator.new a.fill_specific_form :first_name => "Mads", :last_name => "Mobæk" # => Setting 'first_name' to 'Mads' # => Setting 'last_name' to 'Mobæk' 

Is it possible to do the same without a hash? Since all parameters are necessary, I need a method with the following signature:

 fill_specific_form(first_name, last_name) 

In my mind, this would be possible if the body of the method reflected and sorted through its parameters, thereby achieving the same result.

How would you implement this? Is there already a sample / idiom for this? Two obvious benefits would be parameter information in the IDE and no need to check for all hash keys.

What I want to avoid:

 puts "Setting first_name to #{first_name}" puts "Setting last_name to #{last_name}" # and so on 
0
reflection ruby
Aug 11 '10 at 9:00
source share
3 answers

If you have not set other local variables inside the method, local_variables will provide you with a list of method parameter names (if you set other variables, you can simply call local_variables first thing and remember the result). So you can do what you want with local_variables + eval :

 class Automator def fill_specific_form(first_name, last_name) local_variables.each do |var| puts "Setting #{var} to #{eval var.to_s}" end end end Automator.new().fill_specific_form("Mads", "Mobaek") 

Be an adviser that this is pure evil.

And at least for your example

 puts "Setting first_name to #{first_name}" puts "Setting last_name to #{last_name}" 

seems much more reasonable.

You can also do fields = {:first_name => first_name, :last_name => last_name} at the beginning of the method, and then go with your fields.each_pair code.

+3
Aug 11 '10 at 9:11
source share

I don’t quite understand. Do you want to get all parameters in one array?

 def fill_specific_form *args #Process args end 
0
Aug 11 '10 at 9:10
source share

To reflect the parameters of a method (or Proc ), you can use Proc#parameters , Method#parameters or UnboundMethod#parameters :

 ->(m1, o1=nil, *s, m2, &b){}.parameters # => [[:req, :m1], [:opt, :o1], [:rest, :s], [:req, :m2], [:block, :b]] 

However, in your case, I do not understand why you need reflection, since you already know the parameter names anyway.

0
Aug 11 2018-10-11T10:
source share



All Articles