I do this too. In fact, I tend to use the same file for both Ruby and
shell. Suppose the config file has format
KEYWORD=VALUE
ANOTHERKEYWORD=Still another value
etc.
That file can be sourced directly into a shell script, and read into a
Ruby program with the following code …
def read_config(config_file)
result = {}
open(config_file) do |file|
while line = file.gets
key, value = line.chomp.split(“=”)
result[key] = value
end
end
result
end
read_config returns a hash table containing the keys and the values. A
little extra code can handle comments and blank lines and you have a
quick and dirty config reader.
True, it isn’t quite what you asked for, but I’ve found it to be quite
useful. And I really like that one config file works for both Ruby and
shell.
Of course, if your config data is more than just simple keyword/values,
I would suggest taking a look at YAML (or XML).
···
On Wed, 2003-02-19 at 00:20, Björn Lindström wrote:
I like using source files as configuration files for my hacks.
In shell I can easily do that by putting:
source ~/.configfile
or something like that at the top of the script.
Then I can put whatever settings I like in ~/.configfile
There seems to be no straightforward way to do that in Ruby,
neither with eval or with require/include.
I do this too. In fact, I tend to use the same file for both
Ruby and shell. Suppose the config file has format
Well, this is not what I am looking for. The point of the whole
thing is that I want to be able to put loops and stuff into the
configuration file. Is there really no way to just include/source
a file in Ruby?
On Wed, Feb 19, 2003 at 03:27:10PM +0900, Bjrn Lindstrm wrote:
Well, this is not what I am looking for. The point of the whole
thing is that I want to be able to put loops and stuff into the
configuration file. Is there really no way to just include/source
a file in Ruby?
–
Jos Backus / /// Sunnyvale, CA
_/ _/ _/ / ///
_/ _/ _/ /
jos at catnook.com// /// require ‘std/disclaimer’
OK, say that config.rb is a file containing the line:
x = 23
and in my script I do:
load ‘./config.rb’
puts x
this is what I get:
./script.rb:3: undefined local variable or method `x’ for #Object:0x401d1ce0 (NameError)
···
–
Björn Lindström bkhl@privat.utfors.sehem.fyristorg.com/bkhl/
Addr: Ramsta Svista, SE-755 91 Uppsala Ph: 018-398248/073-6171268
Listening to: Tristania: Beyond the Veil (Beyond the Veil)
OK, say that config.rb is a file containing the line:
x = 23
and in my script I do:
load ‘./config.rb’
puts x
this is what I get:
/script.rb:3: undefined local variable or method `x’ for
#Object:0x401d1ce0 (NameError)
···
–
Björn Lindström bkhl@privat.utfors.sehem.fyristorg.com/bkhl/
Addr: Ramsta Svista, SE-755 91 Uppsala Ph: 018-398248/073-6171268
Listening to: Tristania: Beyond the Veil (Beyond the Veil)
I'd expect that. When Ruby is parsing the main program, it has not seen any
assignment to 'x' by the time it gets to line 2. It therefore assumes that x
is a method call, so compiles it the same as
puts self.x
Then it starts running; the load command is executed, and 'x=23' creates a
local variable. But it's too late, line 2 was already parsed, and 'x' is not
treated as a local variable.
You'd think it might work this way, but it doesn't:
x=nil
load './config.rb'
puts x #>> prints nil
Now 'puts x' refers to a local variable, but config.rb isn't setting it. It
must have its own scope for local variables (which I suppose it would, being
a method call)
Now, you could change the main program to:
class <<self
attr_accessor :x
end
load './config.rb'
puts x
and config.rb to:
self.x = 23
and then it works. But that's not pretty.
You'd think there would be a more Rubyesque way of doing this. I thought
about an object which represents your configuration information:
# main.rb
class Config
attr_accessor :x,:y,:z
end
conf = Config.new
conf.instance_eval { load 'config.rb' } # no
puts conf.x
# config.rb
self.x = 23
But 'load' doesn't work in that way inside instance_eval, since it seems to
reset the context to the object 'main'
So I think you're left with reading the file as a string and then eval'ing
it:
x=nil
eval File.open('config.rb').read
puts x
Note the assignment to 'x' is still needed, as explained above. See also
Regards,
Brian.
···
On Wed, Feb 19, 2003 at 03:56:05PM +0900, Björn Lindström wrote:
OK, say that config.rb is a file containing the line:
x = 23
and in my script I do:
load './config.rb'
puts x
this is what I get:
./script.rb:3: undefined local variable or method `x' for #<Object:0x401d1ce0> (NameError)
That’s tidier. The config file can say ‘@x=1’ instead of ‘self.x=1’ which is
cleaner too.
I guess it’s an example of an application which would be cleaner without the
local variable / method dichotomy; ATM there’s no way to invoke an attribute
writer without prefixing it with the object reference.
B.
···
On Thu, Feb 20, 2003 at 01:59:02AM +0900, Mauricio Fern?ndez wrote:
Using instance_eval is a good idea IMHO:
batsman@tux-chan:/tmp$ expand -t 2 h.rb
class Config
attr_accessor :x, :y, :z
end
USEFILE = false
conf = Config.new
conftext = case USEFILE
when true
File.open(“./config.rb”) { |f| f.read }
when false
'self.x = 1; self.y = 2; self.z = “test” ’
end
conf.instance_eval conftext
conf.instance_variables.each do |f|
puts "#{f} => #{conf.instance_eval(f).inspect} "
end
batsman@tux-chan:/tmp$ ruby h.rb @z => “test” @y => 2 @x => 1