Ruby: Unwanted context in exceptions raised within an eval
Question
There seems to be an odd discrepancy between the messages contained in Ruby Exceptions raised directly and raised from within evals. For instance, the following code:
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
Produces the following output:
Rescue foo
Help!
Rescue eval 'foo'
./temp.rb:2:in `foo': Help!
Short of using regexps to sub it out, is there any way I can raise the exception without the context in the second case?
Solution
That is unusual, I've not come across that before. I can't see a way of persuading eval not to add that information, so either you do the regexp munging you mentioned, or you can define your own error type:
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
With output:
Rescue eval 'foo'
Help!
In anything larger than a simple script, defining your own error types is good practice anyway.
(updated to fix code in line with what Chris said in his answer)
OTHER TIPS
Thanks. I was defining my own error anyway, so that's an easy fix.
I've made a slight change, so that the superclass is initialized as well:
class MyException < RuntimeError
attr_accessor :my_message
def initialize(m)
@my_message = String.new(m)
super
end
end
(the String.new call seems to be needed to avoid getting the old behaviour again; presumably Exception.new modifies the message in-place.)