Подтвердить что ты не робот

Как спасти Eval в Ruby?

Я пытаюсь выяснить, как устранить синтаксические ошибки, возникающие при использовании eval() кода в Ruby 1.8.6.

Я бы ожидал следующий код Ruby:

#!/usr/bin/ruby

good_str = "(1+1)"
bad_str = "(1+1"    # syntax error: missing closing paren

begin
    puts eval(good_str)
    puts eval(bad_str)
rescue => exc
    puts "RESCUED!"
end

чтобы получить следующий результат при запуске:

2
RESCUED!

Вместо этого я получаю:

2
eval_rescue.rb:8: (eval):1: compile error (SyntaxError)
(eval):1: syntax error, unexpected $end, expecting ')'

Похоже, что SyntaxError, созданный методом eval, спасается где-то внутри eval, не давая мне возможности справиться с этим сам.

Кто-нибудь знает, как получить нужное поведение (т.е. для моего предложения "rescue", чтобы поймать ошибку из "eval" )?

4b9b3361

Ответ 1

Ну, это было легко...

Оказывается, что по умолчанию оператор "rescue" не обнаруживает исключения all, а только те, которые являются подклассами StandardError. SyntaxError является братом/двоюродным братом StandardError, а не его подклассом, поэтому оператор спасения не захватывает его, если явно не сказано.

Чтобы иметь блокировку all блока спасения, необходимо изменить код на следующее:

#!/usr/bin/ruby

good_str = "(1+1)"
bad_str = "(1+1"    # syntax error: missing closing paren

begin
    puts eval(good_str)
    puts eval(bad_str)
rescue Exception => exc
    puts "RESCUED!"
end

Обратите внимание на изменение в строке "спасение", от "rescue = > exc" до "rescue Exception = > exc".

Теперь, когда вы запускаете код, вы получаете желаемые результаты:

2
RESCUED!

Ответ 2

Brent уже получил ответ, который работает, но я рекомендую спасать от самого маленького набора исключений, с которыми вы можете избавиться. Это гарантирует, что вы не случайно поглощаете то, что не хотите быть.

Таким образом,

begin
  puts eval(good_str)
  puts eval(bad_str)
rescue SyntaxError => se
  puts 'RESCUED!'
end