2010-08-11 47 views
0

方法参数采取以下类:思考 - 以红宝石

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' 

是否有可能做同样没有散?由于需要的所有参数,我想用下面签名的方法:

fill_specific_form(first_name, last_name) 

在我看来这是有可能通过具有方法体反映和遍历其参数,从而达到相同的结果。

你将如何实现这一点?这个模式/习语是否已经存在?两个明显的好处是IDE中的参数信息,而不必检查是否提供了所有的散列键。

我想避免的是:

puts "Setting first_name to #{first_name}" 
puts "Setting last_name to #{last_name}" 
# and so on 
+0

重复的[Ruby - 打印变量名称,然后它的值](http://stackoverflow.com/questions/2603617/ruby-print-the-variable-name-and-then-its-value) – 2010-08-11 23:26:28

+0

This是[有没有办法在ruby中返回方法参数名称](http://StackOverflow.Com/q/2452077/#2452322)。 – 2011-08-21 10:18:50

回答

3

如果设置方法里面没有其他的本地变量,local_variables会给你方法的参数名称的列表(如果你不设置其他变量,你可以叫local_variables第一件事,记得的结果)。所以,你可以做你想做与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") 

然而告知,这是纯粹的邪恶。

至少对于你的榜样

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

似乎更明智。

您也可以在方法开始时做fields = {:first_name => first_name, :last_name => last_name},然后使用您的fields.each_pair代码。

+0

纯粹的邪恶并不是我想要的,也不是我想要的。只是好奇有没有办法做到这一点。我会测试你的建议并回复给你 – 2010-08-11 09:23:40

+0

fields = {:first_name => first_name,:last_name => last_name}是我想要的。谢谢。 – 2010-08-12 08:27:48

+0

我尝试使用Ruby 1.9.3,并且您必须执行#{eval var.to_s}才能使其正常工作,否则您将得到TypeError:无法将符号转换为字符串 – 2012-10-11 03:03:49

0

我不太明白。你想在一个数组中接收所有参数吗?

def fill_specific_form *args 
    #Process args 
end 
+0

不完全。这只会获得通过的值。通过使用与表单元素名称匹配的显式参数名称,我可以设置name = value。请看sepp2k的回答 – 2010-08-11 09:20:08

0

要反映的方法(或Proc的)参数,你可以使用Proc#parametersMethod#parametersUnboundMethod#parameters

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

然而,在你的情况,我不明白为什么你需要反思,因为你无论如何已经知道参数的名字。

+0

这是1.9.2中的新功能吗?这在1.8.7或1.9.1中对我无效。 – sepp2k 2010-08-11 18:31:10

+0

@ sepp2k:是的,'Proc#parameters'是1.9.2中的新功能。 – 2010-08-11 19:01:31