# How to evaluate file as Ruby code?

**URL:** <https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839>\
**Category:** Ruby\
**Created:** [February 22, 2006, 3:09pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839 "2006-02-22T15:09:17Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2006, 3:09pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/1 "2006-02-22T15:09:17Z")

</div>

How do I evaluate a text file as a sequence of Ruby statements?  
(For those who happen to know Perl: I would like to have an  
equivalent of the Perl ‘do FILENAME’ feature).

For example, I have a file “foo” which contains the lines

abc=4  
def=5

I would like to “evaluate” the file such that after this, the  
variable abc is set to 4 and def is set to 5.

I tried the following:

eval(File.new(“foo”).read)

But after this, abc is still undefined. What am I doing wrong here?

Ronald

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2006, 3:25pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/2 "2006-02-22T15:25:02Z")

</div>

Ronald F. wrote:

> variable abc is set to 4 and def is set to 5.
> 
> I tried the following:
> 
> eval(File.new(“foo”).read)
> 
> But after this, abc is still undefined. What am I doing wrong here?
> 
> Ronald

require will load and evaluate the file once, but will not load  
a file that has already been 'require’d

load will load and evaluate the file, it will reload and  
re-evaluate.

Cheers  
Chris

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2006, 3:31pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/3 "2006-02-22T15:31:21Z")

</div>

On Wed, 2006-02-22 at 23:08 +0900, Ronald F. wrote:

> variable abc is set to 4 and def is set to 5.
> 
> I tried the following:
> 
> eval(File.new(“foo”).read)
> 
> But after this, abc is still undefined. What am I doing wrong here?

It’s just the way Ruby works with respect to deciding whether ‘a’ is a  
variable or a method. Your assignment didn’t get ‘seen’ except inside an  
eval. You can use eval again to get back there (changed the var names,  
def is a keyword):

```
eval File.read('foo.rb')
p eval('a')
# => 4
p eval('b')
# => 5

```

But that’s a hack, and really I think you should consider an alternate  
design - local variables are supposed to be, well, local. Maybe  
constants or (though it pains me to say it) globals would be more  
suitable?

Another technique I’ve used with great success is having a class that  
acts as context for an external script, providing methods and holding  
data in instance variables. You supply a script similar to yours above,  
except using instance variables, which is then instance\_eval’d in an  
instance of that class, after which you have a self-contained  
configuration, or whatever else it is you made.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2006, 3:34pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/4 "2006-02-22T15:34:26Z")

</div>

> > For example, I have a file “foo” which contains the lines
> > 
> > abc=4  
> > def=5
> > 
> > I would like to “evaluate” the file such that after this, the  
> > variable abc is set to 4 and def is set to 5.

> load will load and evaluate the file, it will reload and  
> re-evaluate.

Keep in mind that using load keeps local variables local to their scope  
within the file:

tc@tc8 ~ $ cat foo.txt  
a = 5  
@b = 10

tc@tc8 ~ $ irb  
irb(main):001:0\> load ‘foo.txt’  
=\> true  
irb(main):002:0\> @b  
=\> 10  
irb(main):003:0\> a  
NameError: undefined local variable or method `a’ for  
#\<Object:0xb7d37970  
@b=10\>

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2006, 8:09pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/5 "2006-02-22T20:09:24Z")

</div>

Ross B. wrote:

> Another technique I’ve used with great success is having a class that  
> acts as context for an external script, providing methods and holding  
> data in instance variables. You supply a script similar to yours above,  
> except using instance variables, which is then instance\_eval’d in an  
> instance of that class, after which you have a self-contained  
> configuration, or whatever else it is you made.

For example, [http://raa.ruby-lang.org/project/script](http://raa.ruby-lang.org/project/script)

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2006, 4:07pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/6 "2006-02-22T16:07:03Z")

</div>

On Wed, 22 Feb 2006, Ronald F. wrote:

> variable abc is set to 4 and def is set to 5.
> 
> I tried the following:
> 
> eval(File.new(“foo”).read)
> 
> But after this, abc is still undefined. What am I doing wrong here?

first, def=5 is a problem because def is a reserved word  
So make ‘foo’ to state  
a=4  
b=5

and then try:

a = b = nil  
eval(File.new(‘foo’).read)  
puts “a=#{a} b=#{b}”

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 23, 2006, 2:18pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/7 "2006-02-23T14:18:52Z")

</div>

> load will load and evaluate the file, it will reload and  
> re-evaluate.

This is exactly what I’m looking for (and for my problem it is  
OK that I revert to local variables).

But now I have a new problem: Exceptions thrown by ‘load’ can not  
be caught!

For example,

begin  
load “.defaultpar”  
rescue  
puts “file not found”  
end

If the file does not exist, I get the error message

in `load’: no such file to load – .defaultpar (LoadError)

Of course I can circumvent it by testing before for the existence  
of the file, but I wonder how I can find (from the Ruby specification),  
which exceptions can be caught by “rescue” and which ones can not.

Ronald

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 23, 2006, 2:24pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/8 "2006-02-23T14:24:57Z")

</div>

Hi –

On Thu, 23 Feb 2006, Ronald F. wrote:

> Of course I can circumvent it by testing before for the existence  
> of the file, but I wonder how I can find (from the Ruby specification),  
> which exceptions can be caught by “rescue” and which ones can not.

I believe rescue on its own catches RuntimeError and its descendants.  
If you want to rescue something else, you can do:

rescue LoadError

David

–  
David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” chapters now available  
from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 23, 2006, 5:39pm UTC](https://www.ruby-forum.com/t/how-to-evaluate-file-as-ruby-code/71839/9 "2006-02-23T17:39:25Z")

</div>

I think rescue by default only catches StandardError (and descendants).

Maybe:

rescue Exception =\> ex

Will catch this one?

-Harold
