Forum: Ruby How to evaluate file as Ruby code?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
26198eab52c6dcded426d133703828ec?d=identicon&s=25 unknown (Guest)
on 2006-02-22 15:09
(Received via mailing list)
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
23172b6630dc631a134c9bad2fec2a39?d=identicon&s=25 ChrisH (Guest)
on 2006-02-22 15:25
(Received via mailing list)
Ronald Fischer 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 <file> will load and evaluate the file once, but will not load
a file that has already been 'require'd

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

Cheers
Chris
A9b6a93b860020caf9d2d1d58c32478f?d=identicon&s=25 Ross Bamford (Guest)
on 2006-02-22 15:31
(Received via mailing list)
On Wed, 2006-02-22 at 23:08 +0900, Ronald Fischer 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.
9c7f2f44463d1d4890f73e8a8229dd29?d=identicon&s=25 Caleb Tennis (Guest)
on 2006-02-22 15:34
(Received via mailing list)
>> 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 <file> 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>
B7f73e9f9d35be6a44b15f603f2910d4?d=identicon&s=25 Wybo Dekker (Guest)
on 2006-02-22 16:07
(Received via mailing list)
On Wed, 22 Feb 2006, Ronald Fischer 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}"
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-02-22 20:09
(Received via mailing list)
Ross Bamford 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
26198eab52c6dcded426d133703828ec?d=identicon&s=25 unknown (Guest)
on 2006-02-23 14:18
(Received via mailing list)
> load <file> 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
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-02-23 14:24
(Received via mailing list)
Hi --

On Thu, 23 Feb 2006, Ronald Fischer 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 (dblack@wobblini.net)
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
7f891fbe8e3bae7f9fe375407ce90d9d?d=identicon&s=25 Harold Hausman (Guest)
on 2006-02-23 17:39
(Received via mailing list)
I think rescue by default only catches StandardError (and descendants).

Maybe:

rescue Exception => ex

Will catch this one?

-Harold
This topic is locked and can not be replied to.