ruby - 如何从eval内部返回?

时间:2011-07-28 19:06:56

标签: ruby eval

我有一个代码需要在eval中使用。有时我需要退出eval代码,但我的尝试会导致错误。

E.g:

# expected to see 1, 2 and 5; not 3 nor 4; and no errors
eval "puts 1; puts 2; return; puts 3; puts 4"   # => Error: unexpected return
puts 5

我尝试了returnendexitbreak,但我无法取得成功。 exit不会引发错误,但是我没有得到错误。

(注意:我知道eval是邪恶的,但在这种情况下我需要使用它。)

5 个答案:

答案 0 :(得分:4)

谢谢大家,但我找到了一个最符合我问题的解决方案:

lambda do
  eval "puts 1; puts 2; return; puts 3; puts 4"
end.call
puts 5

通过这种方式,可以在return内使用直观的eval关键字,以便成功摆脱它。

在这种情况下,我不喜欢类似条件的解决方案,因为它会迫使我(或用户)在最后添加end

关于使用throw/catchbreak,我认为return关键字更直观。

答案 1 :(得分:3)

eval'd代码正在这个地方运行。它不是一个功能或块。没有评估,你会怎么做?可能是这样的:

puts 1
puts 2 
if(conditionFor3And4) 
  puts 3 
  puts 4
end

答案 2 :(得分:3)

你不能。你可以退出方法,并打破块或循环,但不是eval。

您可以尝试使用throw / catch块

eval " 
  should_stop = true
  catch :stop do
    puts 1  
    puts 2 
    throw :stop if should_stop
    puts 3
  end
"

或者这个:

  should_stop = true
  catch :stop do
  eval " 
    puts 1  
    puts 2 
    throw :stop if should_stop
    puts 3
 "
 end

或者只是像Mchl那样做一个条件,因为你可能希望它有条件停止,而不仅仅是总是,但是抛出catch会让你跳出一个块,无论你有多少级别,这使它更加健壮,如果你需要突破嵌套循环或类似的东西。

答案 3 :(得分:2)

你可以使用条件而不是早期返回。

答案 4 :(得分:0)

您可以非常高兴地定义一个函数并在脚本末尾执行它,如下所示:

def ev(s)
  eval("def doStuff()\n" + s + "\nend\ndoStuff()")
end

ev("
    1
    return 2
    3
")

#=> 2

Demo