2011-09-12 46 views
3

我有一个方法接受将被调用的lambda或将被评估的字符串。 为什么下面的方法失败:Ruby中奇怪的过程错误

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 
+0

错字?真的拼写epr? –

+0

是错字,修正。 –

+1

只要确保。很高兴看到你有两个很好的答案。 –

回答

3

在这里:

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

你有一个Proc最终在expr这是一个封闭在expr所以当PROC评估,它试图eval本身,因为拉姆达内expr是拉姆达本身。

在这里:

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

关闭超过foo其中提到expr原始字符串值,所以没有时髦的自我指涉的混乱,你将最终在字符串中使用eval

+0

明白了!谢谢。 –

+0

@ream88:维克多是第一个,所以你应该给他勾选标记(我不会个人承认,诚实),我只是想澄清一下发生了什么。 –

+0

+1呼出“自我指涉”。 (也赞成维克多是正确的_and_第一。) –

3

你是可变expr分配拉姆达。该lambda试图评估变量expr的内容(即试图评估自己)。 eval仅需要字符串,这就是引发异常的原因。