# Exceptions and eval'ing a string

**URL:** <https://www.ruby-forum.com/t/exceptions-and-evaling-a-string/115019>\
**Category:** Ruby\
**Created:** [September 19, 2007, 7:44pm UTC](https://www.ruby-forum.com/t/exceptions-and-evaling-a-string/115019 "2007-09-19T19:44:02Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [September 19, 2007, 7:44pm UTC](https://www.ruby-forum.com/t/exceptions-and-evaling-a-string/115019/1 "2007-09-19T19:44:02Z")

</div>

Here’s my situation

I have a setup such as:

----task.rb----  
class Task  
def initialize(name, &action)  
@name = name  
@action = action  
end

def run  
@action.call(self)  
end  
end

----task\_runner.rb----  
require ‘task’

t = Task.new(‘task\_1’) { |t| puts t.name }  
t.run # =\> thing

what i am now trying to do is put the Task creation code inside a file  
and eval that as a string

----thing.task----  
Task.new(‘task\_1’) P |t| puts t.name }

----task\_runner.rb----  
require ‘task’  
def load\_task  
@t = eval(‘thing.task’)  
end

@t = nil  
load\_task  
@t.run

and this works…however, the difference is that if an exception is  
thrown as part of the Task’s action (when it is run) eval craps out with  
an exception like

(eval):15

and it brings down the entire script, which is a bad thing because i’m  
running each task in a thread. this doesn’t happen obviously when i’m  
not eval’ing.

can someone explain to me what is going on? I’m thinking it’s a  
scoping/context thing, but i’m not really sure.

Chris

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [September 19, 2007, 8:12pm UTC](https://www.ruby-forum.com/t/exceptions-and-evaling-a-string/115019/2 "2007-09-19T20:12:26Z")

</div>

sorry, there’s a typo in the example, that eval line should read

@t = eval(IO.read(“test.task”))

rather than

@t = eval(“test.task”)

problem still stands.

Chris H. wrote:

> Here’s my situation
> 
> I have a setup such as:
> 
> ----task.rb----  
> class Task  
> def initialize(name, &action)  
> @name = name  
> @action = action  
> end
> 
> def run  
> @action.call(self)  
> end  
> end
> 
> ----task\_runner.rb----  
> require ‘task’
> 
> t = Task.new(‘task\_1’) { |t| puts t.name }  
> t.run # =\> thing
> 
> what i am now trying to do is put the Task creation code inside a file  
> and eval that as a string
> 
> ----thing.task----  
> Task.new(‘task\_1’) P |t| puts t.name }
> 
> ----task\_runner.rb----  
> require ‘task’  
> def load\_task  
> @t = eval(‘thing.task’)  
> end
> 
> @t = nil  
> load\_task  
> @t.run
> 
> and this works…however, the difference is that if an exception is  
> thrown as part of the Task’s action (when it is run) eval craps out with  
> an exception like
> 
> (eval):15
> 
> and it brings down the entire script, which is a bad thing because i’m  
> running each task in a thread. this doesn’t happen obviously when i’m  
> not eval’ing.
> 
> can someone explain to me what is going on? I’m thinking it’s a  
> scoping/context thing, but i’m not really sure.
> 
> Chris

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [September 19, 2007, 8:18pm UTC](https://www.ruby-forum.com/t/exceptions-and-evaling-a-string/115019/3 "2007-09-19T20:18:54Z")

</div>

On 9/19/07, Chris H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Here’s my situation  
> and this works…however, the difference is that if an exception is  
> thrown as part of the Task’s action (when it is run) eval craps out with  
> an exception like
> 
> (eval):15
> 
> and it brings down the entire script, which is a bad thing because i’m  
> running each task in a thread. this doesn’t happen obviously when i’m  
> not eval’ing.

You can handle those exceptions by adding ‘rescue’ clause to your run  
method.  
i.e.  
def run  
begin  
@action.call…  
rescue Exception =\> ex  
# do whatever you want with ex  
end  
end

You have to  
Note: in this case the begin and end may be omitted:

def run  
@action.call…  
rescue Exception =\> ex  
# do whatever you want with ex  
end

To catch syntax errors, you have to add begin/rescue/end around the  
eval command.

Have a look at ruby exception hierarchy in zenspider’s Ruby QuickRef,  
and carefully consider what do you want to catch and what not (to  
allow ctrl-break to function etc.)

Finally, you can control exception propagation using  
Thread.abort\_on\_exception.

HTH,

Jano

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [September 19, 2007, 11:00pm UTC](https://www.ruby-forum.com/t/exceptions-and-evaling-a-string/115019/4 "2007-09-19T23:00:25Z")

</div>

On 19.09.2007 19:44, Chris H. wrote:

> end  
> t.run # =\> thing
> 
> what i am now trying to do is put the Task creation code inside a file  
> and eval that as a string
> 
> ----thing.task----  
> Task.new(‘task\_1’) P |t| puts t.name }  
> ^  
> I’d say you get a syntax error here.

> and this works…however, the difference is that if an exception is  
> thrown as part of the Task’s action (when it is run) eval craps out with  
> an exception like
> 
> (eval):15

That statement seems illogical, because eval is only used for loading  
the task but you claim that eval throws during execution of the task.  
What am I missing here?

> and it brings down the entire script, which is a bad thing because i’m  
> running each task in a thread. this doesn’t happen obviously when i’m  
> not eval’ing.
> 
> can someone explain to me what is going on? I’m thinking it’s a  
> scoping/context thing, but i’m not really sure.

Personally I dislike the way you use instance variables here. Why don’t  
you just let load\_task return the new Task and assign the result to a  
local variable?

Kind regards

robert
