[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Dynamically requiring files - scoping issues

Gordon Hartley

3/20/2005 10:03:00 PM

Hi,

Given the source and output below, it should be fairly obvious what
I'm trying to do (doing code generation / automation stuff.)

Page 124 of Pickaxe (2nd Ed.) mentions that variables are not
propogated to the scope that loads/requires them, so is there any way
of referring to / accessing them?

I've resolved it as per main2.rb excerpt below, but was wondering
whether there is a 'cleaner' (free or minimal eval()) solution?

Contrived example below, which results in:
Got to here in one.rb
Got to here in two.rb
undefined local variable or method `one' for main:Object (NameError)

Thanks,
Gordon

### dynamic/one.rb ###
one = Needed.new("1")
puts "Got to here in one.rb"

### dynamic/two.rb ###
two = Needed.new("2")
puts "Got to here in two.rb"

### needed/needed.rb ###
class Needed
attr_accessor :test
def initialize(test)
@test = test
end
end

class DoStuff
def DoStuff.go(needed_array)
needed_array.each do |needed|
# do stuff with needed.....
end
end
end

### main.rb ###
require 'needed/needed'

container = []

Dir["dynamic/*.rb"].each do |file_name|
require "#{file_name[0..-4]}"
end

Dir.chdir("./dynamic")

Dir["*.rb"].each do |file_name|
eval("container << #{file_name[0..-4]}")
end

DoStuff.go(container)

### main2.rb excerpt, not part of example ###

Dir["*.rb"].each do |file_name|
eval_me = File.open(file_name).readlines.to_s
eval(eval_me)
eval("container << " + file_name[0..-4].to_s)
end


1 Answer

Joel VanderWerf

3/20/2005 11:17:00 PM

0

Gordon Hartley wrote:
...
> Page 124 of Pickaxe (2nd Ed.) mentions that variables are not
> propogated to the scope that loads/requires them, so is there any way
> of referring to / accessing them?

The approach I tend to use is in my "script" library:

http://redshift.sourceforge.n...

Briefly, Script.load and Script.require still read and eval the file,
but they return a module which contains the constants and methods
defined at the top level in the file (and in any local files required by
that file). So if you're willing to live with the following syntax

ONE = Needed.new("1")

or

def one
Needed.new("1")
end

then you can retrieve these values with something like

Script.require(filename).const_get filename[0..-4].upcase

or

Script.require(filename).send filename[0..-4]

It might even work out to just put a line of the form

NEEDED = Needed.new("1")

in each file and then retrieve it with

Script.require(filename)::NEEDED

(But probably I don't understand something about the rest of your program.)

...
> eval_me = File.open(file_name).readlines.to_s

More simply:

eval_me = File.read(file_name)

HTH.