Ruby中奇怪的Proc错误

时间:2011-09-12 07:44:49

标签: ruby lambda ruby-1.9.2

我有一个方法接受将被调用的lambda或将被评估的字符串。 为什么以下方法失败:

def test(expr)
  expr = expr.respond_to?(:call) ? expr : ->{ eval(expr) }
  expr.call
end

test 'puts 1'
# => TypeError: can't convert Proc into String

但这一项工作:

def test(expr)
  foo = expr
  expr = expr.respond_to?(:call) ? expr : ->{ eval(foo) }
  expr.call
end

test 'puts 1'
# => 1

2 个答案:

答案 0 :(得分:3)

您正在将lambda分配给变量expr。该lambda试图评估变量expr的内容(即尝试评估自己)。 eval只需要字符串,这就是引发异常的原因。

答案 1 :(得分:3)

在这里:

expr = expr.respond_to?(:call) ? expr : ->{ eval(expr) }

你最终得到的expr中的Proc是expr的封闭,因此当评估Proc时,它会尝试eval本身,因为expr里面的foo = expr expr = expr.respond_to?(:call) ? expr : ->{ eval(foo) } lambda就是lambda本身。

在这里:

foo

闭包超过expr,它引用eval的原始字符串值,因此没有时髦的自引用混淆,你最终会在字符串上使用{{1}}。