Как спасти 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, не давая мне возможности обработать его самостоятельно.
Кто-нибудь имеет какие-либо идеи, как получить поведение, которое я хочу (то есть, для моего условия 'спасения', чтобы поймать ошибку из 'eval')?
2 ответа
Ну, это было легко...
Оказывается, что по умолчанию оператор "rescue" перехватывает не все исключения, а только те, которые являются подклассами StandardError. SyntaxError - это родственник / двоюродный брат StandardError, а не его подкласс, поэтому оператор спасения не фиксирует его, если ему явно не сказано.
Чтобы аварийный блок захватывал все исключения, вам нужно изменить код на следующий:
#!/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" с "rescue => exc" на "rescue Exception => exc".
Теперь, когда вы запускаете код, вы получаете желаемые результаты:
2
RESCUED!
Брент уже получил ответ, который работает, но я рекомендую избавиться от наименьшего набора исключений, с которым вы можете сойти. Это гарантирует, что вы случайно не сожраете то, чем не хотите быть.
Таким образом,
begin
puts eval(good_str)
puts eval(bad_str)
rescue SyntaxError => se
puts 'RESCUED!'
end