Ruby:在eval中引发的异常中不需要的上下文

时间:2009-04-16 09:21:10

标签: ruby exception eval

直接引发的Ruby Exceptions中包含的消息与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!

如果没有使用regexp将其分解出来,有没有办法在第二种情况下没有上下文的情况下引发异常?

2 个答案:

答案 0 :(得分:2)

感谢。无论如何,我正在定义自己的错误,所以这很容易解决。

我做了一些小改动,所以超类也被初始化了:

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

(似乎需要String.new调用以避免再次出现旧行为;可能是Exception.new就地修改了消息。)

答案 1 :(得分:1)

这很不寻常,我之前没遇到过。我无法看到说服eval不添加该信息的方法,所以要么你执行你提到的regexp,要么你可以定义自己的错误类型:

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!

在比简单脚本更大的任何内容中,无论如何都要定义自己的错误类型。

(根据克里斯在答案中所说的内容更新以修复代码)