Ruby: нежелательный контекст в исключениях, возникающих в eval - PullRequest
1 голос
/ 16 апреля 2009

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

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!

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

Ответы [ 2 ]

2 голосов
/ 16 апреля 2009

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

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

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

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

1 голос
/ 16 апреля 2009

Это необычно, я не сталкивался с этим раньше. Я не вижу способа убедить 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!

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

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

...