Рубин:Нежелательный контекст в исключениях, возникающих при проверке
Вопрос
Кажется, существует странное несоответствие между сообщениями, содержащимися в исключениях Ruby, вызываемых напрямую, и сообщениями, создаваемыми из evals.Например, следующий код:
def foo
raise "Help!"
end
puts "\nRescue foo"
begin
foo
rescue RuntimeError => e
puts e.message
end
puts "\nRescue eval 'foo'"
begin
eval "foo"
rescue RuntimeError => e
puts e.message
end
Производит следующий вывод:
Rescue foo
Help!
Rescue eval 'foo'
./temp.rb:2:in `foo': Help!
Если не использовать регулярные выражения для его замены, есть ли способ вызвать исключение без контекста во втором случае?
Решение
Это необычно, я с таким раньше не сталкивался.Я не вижу способа убедить eval не добавлять эту информацию, поэтому либо вы выполняете упомянутую вами обработку регулярных выражений, либо можете определить свой собственный тип ошибки:
class MyError < RuntimeError
attr_accessor :my_message
def initialize(m)
@my_message = m.dup
super
end
end
def foo
raise MyError.new("Help!")
end
puts "\nRescue eval 'foo'"
begin
eval "foo"
rescue RuntimeError => e
puts e.my_message
end
С выводом:
Rescue eval 'foo'
Help!
В любом сценарии, превышающем простой сценарий, определение собственных типов ошибок в любом случае является хорошей практикой.
(обновлено, чтобы исправить код в соответствии с тем, что сказал Крис в своем ответе)
Другие советы
Спасибо.В любом случае я определил свою собственную ошибку, так что это легко исправить.
Я внес небольшое изменение, чтобы суперкласс также инициализировался:
class MyException < RuntimeError
attr_accessor :my_message
def initialize(m)
@my_message = String.new(m)
super
end
end
(вызов String.new, по-видимому, необходим, чтобы избежать повторного появления старого поведения;предположительно Exception.new изменяет сообщение на месте.)