Google 网上论坛不再支持新的 Usenet 帖子或订阅项。历史内容仍可供查看。

Sourcing files

已查看 0 次
跳至第一个未读帖子

Björn Lindström

未读,
2003年2月19日 00:20:082003/2/19
收件人
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.

How do you suggest I go about this?

--
Björn Lindström <bk...@privat.utfors.se> hem.fyristorg.com/bkhl/
Addr: Ramsta Svista, SE-755 91 Uppsala Ph: 018-398248/073-6171268
Listening to Massive Attack: Teardrop (Mezzanine)

Jim Weirich

未读,
2003年2月19日 00:58:192003/2/19
收件人
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

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 <shudder> XML).

--
-- Jim Weirich jwei...@one.net http://w3.one.net/~jweirich
---------------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

Gavin Sinclair

未读,
2003年2月19日 01:10:002003/2/19
收件人
On Wednesday, February 19, 2003, 4:58:19 PM, Jim wrote:


> Of course, if your config data is more than just simple keyword/values,
> I would suggest taking a look at YAML (or <shudder> XML).


That should be "<shudder> XML </shudder>".

# Sorry.

Gavin


Björn Lindström

未读,
2003年2月19日 01:27:102003/2/19
收件人
Jim Weirich <jwei...@one.net> [20030219 06:58]:

> 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?

--
Björn Lindström <bk...@privat.utfors.se> hem.fyristorg.com/bkhl/
Addr: Ramsta Svista, SE-755 91 Uppsala Ph: 018-398248/073-6171268

Listening to Howard Shore

Jos Backus

未读,
2003年2月19日 01:32:302003/2/19
收件人
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?

load "file"

?

--
Jos Backus _/ _/_/_/ Sunnyvale, CA
_/ _/ _/
_/ _/_/_/
_/ _/ _/ _/
jos at catnook.com _/_/ _/_/_/ require 'std/disclaimer'

Björn Lindström

未读,
2003年2月19日 01:56:052003/2/19
收件人
Jos Backus <j...@catnook.com> [20030219 07:32]:
> load "file"
>
> ?

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 <bk...@privat.utfors.se> hem.fyristorg.com/bkhl/
Addr: Ramsta Svista, SE-755 91 Uppsala Ph: 018-398248/073-6171268

Listening to: Tristania: Beyond the Veil (Beyond the Veil)

Robert

未读,
2003年2月19日 02:57:512003/2/19
收件人

Your config file should've read

$x=23

Since x should be a global variable. You can use @@x alternatively but I
don't recommend this in your case.

robert

"Björn Lindström" <bk...@privat.utfors.se> schrieb im Newsbeitrag
news:20030219065...@lucien.dreaming...


> Jos Backus <j...@catnook.com> [20030219 07:32]:
> > load "file"
> >
> > ?
>
> 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:
>

Robert Feldt

未读,
2003年2月19日 09:44:362003/2/19
收件人
On Wed, 19 Feb 2003, Björn Lindström wrote:

> Jos Backus <j...@catnook.com> [20030219 07:32]:
> > load "file"
> >
> > ?
>
> 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)
>

Well, what about:

File.open("./config.rb") {|f| eval f.read}
puts x

?

/Robert Feldt


dbl...@candle.superlink.net

未读,
2003年2月19日 10:37:112003/2/19
收件人
Hi --

The local variable x will only exist in the scope of the eval, so
you'll get the same error.


David

--
David Alan Black
home: dbl...@candle.superlink.net
work: blac...@shu.edu
Web: http://pirate.shu.edu/~blackdav


Brian Candler

未读,
2003年2月19日 10:41:032003/2/19
收件人
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)

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
http://www.rubygarden.org/ruby?LocalVariablesAndBlocks/CurrentBehaviour

Regards,

Brian.

Robert Feldt

未读,
2003年2月19日 11:29:072003/2/19
收件人
On Thu, 20 Feb 2003 dbl...@candle.superlink.net 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)
> > >
> > Well, what about:
> >
> > File.open("./config.rb") {|f| eval f.read}
> > puts x
>
> The local variable x will only exist in the scope of the eval, so
> you'll get the same error.
>

Hi David,

Thats right. I was too quick on the trigger there.

It would work for constants though

$ ruby -v -e 'eval "X = 1"; p X'
ruby 1.8.0 (2003-02-13) [i386-mingw32]
1

Regards,

Robert Feldt

Mauricio Fernández

未读,
2003年2月19日 11:59:022003/2/19
收件人
On Thu, Feb 20, 2003 at 12:41:03AM +0900, Brian Candler wrote:
> 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'
>

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

--
_ _
| |__ __ _| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Debian is like Suse with yast turned off, just better. :)
-- Goswin Brederlow

Brian Candler

未读,
2003年2月19日 16:19:292003/2/19
收件人
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

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.

Robert Feldt

未读,
2003年2月21日 01:35:132003/2/21
收件人
Hi,

It struck me that you can actually accomplish what the orig poster wants
using eval and DATA. Unconventional, has drawbacks and not what you'd
typically do in his situation but anyway:

$ cat config
x = 1

$ cat c.rb
eval(File.open("config") {|f| f.read} + DATA.read)
__END__

p x

$ ruby -v c.rb

0 个新帖子