2009-04-16 6 views
1

Кажется, что существует нечетное несоответствие между сообщениями, содержащимися в исключениях Ruby, поднятыми напрямую и поднятыми изнутри evals. Например, следующий код:Ruby: Нежелательный контекст в исключениях, возникающих в пределах eval

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! 

Краткое использования регэкспы качнуть его, есть ли способ, что я могу поднять исключение без контекста в секунду дело?

ответ

1

Это необычно, я не сталкивался с этим раньше. Я не могу видеть способ убедить Eval не добавлять эту информацию, так как вы делаете регулярное выражение munging вы упомянули, или вы можете определить свой собственный тип ошибки:

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! 

В любом случае, чем простой скрипт, определение ваших собственных типов ошибок является хорошей практикой в ​​любом случае.

(обновлено, чтобы исправить код в соответствии с тем, что сказал Крис в своем ответе)

2

Спасибо. Я все равно определял свою собственную ошибку, так что это простое исправление.

Я сделал небольшое изменение, так что суперкласс инициализируется, а также:

class MyException < RuntimeError 
    attr_accessor :my_message 
    def initialize(m) 
    @my_message = String.new(m) 
    super 
    end 
end 

(вызов String.new, как представляется, необходимо, чтобы избежать старое поведение снова, по-видимому Exception.new изменяет сообщение на месте.)

+0

Хорошо все указывает. –