开发者

Weird Proc error in Ruby

I have a method accepting a lambda which will be called or a string which will be evaluated. Why does the fo开发者_运维问答llowing method fail:

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

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

But this one work:

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

test 'puts 1'
# => 1


In here:

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

You end up with a Proc in expr that is a closure over expr so when the Proc is evaluated, it tries to eval itself because the expr inside the lambda is the lambda itself.

In here:

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

the closure is over foo which refers to the original String value of expr so there is no funky self-referential confusion and you'll end up using eval on a String.


You are assigning lambda to variable expr. That lambda tries to eval content of variable expr (i.e. tries to eval itself). eval expects only string, that is why exception is raised.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜