Ruby 访问哈希键作为eval的参数

Ruby 访问哈希键作为eval的参数,ruby,Ruby,假设我有一个方法 def test_eval(formula, num) eval(formula) end 那么我可以说 p test_eval("2 + num", 3) 在eval过程中,它将看到num在此上下文中定义为3,并将打印出5 假设我想在公式中允许任意变量名。例如,我想计算公式 test_eval("2 + num1 + num2", 3, 5) 我可以修改方法签名以接受名为num1和num2的两个参数,但是有没有一种方法可以让我不必硬编码签名,只接受变量名的散列 比

假设我有一个方法

def test_eval(formula, num)
   eval(formula)
end
那么我可以说

p test_eval("2 + num", 3)
在eval过程中,它将看到
num
在此上下文中定义为3,并将打印出5

假设我想在公式中允许任意变量名。例如,我想计算公式

test_eval("2 + num1 + num2", 3, 5)
我可以修改方法签名以接受名为
num1
num2
的两个参数,但是有没有一种方法可以让我不必硬编码签名,只接受变量名的散列

比如说

test_eval("2 + num1 + num2", {:num1 => 3, :num2 => 5})
我的方法将计算公式并返回10。我如何定义一个方法,允许我进行此调用并返回适当的结果

def test_eval(formula, params)
   params.each do |key, value|
     formula = formula.gsub(key.to_s,value.to_s)
   end

   eval(formula)
end
不过,我同意其他人的看法:这不是一个好主意:

test_eval('`rm -rf /` # Oops.')
迟到(如果你真的想和
eval
一起参加派对):

需要“ostruct”
OpenStruct.new({:num1=>3,:num2=>5}).instance_eval(“2+num1+num2”)=>10

test\u eval('a+aa',:a=>1,:aa=>2)时会发生什么情况?这个方法还有很多其他的漏洞。你为什么要这么做呢?我怀疑您已经决定
eval
是解决方案,现在您正试图在备份和重新开始可能更好的时候让它工作。@muistooshort
eval
无疑是最容易想到的解决方案,因为我对允许其他人在公式的上下文中传递他们自己的公式以及他们自己的变量很感兴趣。这些公式可以是任意的ruby代码,而不是像数学公式解析器这样的特定代码。如果我使用
$SAFE
来保护它呢?这样会更好(还是没那么糟糕)?不太好<代码>$SAFE不安全。这是一个插件,一个事后的想法。像这样的功能必须从一开始就内置。
$SAFE
中有漏洞。一般来说,您不应该仅仅依赖Ruby内置的隔离特性,而应该在Ruby之外使用一些隔离。例如,您可以在两个单独的AppDomain中运行两个IronRuby实例。或者在不同的安全上下文中运行两个JRuby实例。或者在两个单独的操作系统进程中运行两个Rubinius/YARV/where实例。依赖.NET、Java或操作系统的隔离功能,而不是Ruby(或除此之外)。如果任意用户不提供输入,eval还会是一个问题吗?你说:“我对允许他人传递自己的公式很感兴趣”和“公式可以是任意的Ruby代码”,这听起来非常危险。如果你能完全控制这些公式,那么它就不会那么危险了……但是,如果你能完全控制,也许有一种方法可以避免传递任意的Ruby代码字符串?
test_eval('`rm -rf /` # Oops.')