YAML.load_file problems

Hi,

i have a program where several things are hard coded
for production i need a config file now, must be editable
and readable by hand, so i decided to try with YAML

program with hard coded stuff =

require "highline/import"

CVSEXE="//foobar/c$/tools/cvsnt/cvs.exe"

cvsrepos=%w[test test1 foo bar foobar]
cvsuser = ask("Enter CVS User: ") {|q|
q.default = "#{ENV["USERNAME"]}"
q.echo = true}
cvspass = ask("Enter your password: ") { |q| q.echo = '*' }

cvsrepos.each {|x|
puts "Login CVS Repository >> #{x} ..."
IO.popen("#{CVSEXE} -d
:pserver:#{cvsuser}:#{cvspass}@cvsprod:d:/cvsrepos/#{x} login")
}
puts "Login successful !!"

i tried with YAML, first step =

require 'yaml'
require "highline/import"

CVSEXE="//foobar/c$/tools/cvsnt/cvs.exe"

cvsrepos=YAML.load_file( "config.yaml" )

cvsuser = ask("Enter CVS User: ") {|q|
q.default = "#{ENV["USERNAME"]}"
q.echo = true}
cvspass = ask("Enter your password: ") { |q| q.echo = '*' }

cvsrepos.each {|x|
puts "Login CVS Repository >> #{x} ..."
IO.popen("#{CVSEXE} -d
:pserver:#{cvsuser}:#{cvspass}@cvsprod:d:/cvsrepos/#{x} login")
}
puts "Login successful !!"

config.yaml looks like =

···

---
- test
- test1
- foo
- bar
- foobar

works fine, but now i want to get the CVSEXE path also into that
yamlfile, i tried

require 'yaml'
require "highline/import"

YAML.load_file( "config.yaml" )

cvsuser = ask("Enter CVS User: ") {|q|
q.default = "#{ENV["USERNAME"]}"
q.echo = true}
cvspass = ask("Enter your password: ") { |q| q.echo = '*' }

cvsrepos.each {|x|
puts "Login CVS Repository >> #{x} ..."
IO.popen("#{CVSEXE} -d
:pserver:#{cvsuser}:#{cvspass}@cvsprod:d:/cvsrepos/#{x} login")
}
puts "Login successful !!"

but that didn't work, my config.yaml looks like =

---
CVSEXE:"//foobar/c$/tools/cvsnt/cvs.exe"
---
cvsrepos:
- test
- test1
- foo
- bar
- foobar

What't the correct YAML Syntax and how do i access the different
section from my script that loads the yaml file ?

Regards, Gilbert

Alle lunedì 12 marzo 2007, Rebhan, Gilbert ha scritto:

What't the correct YAML Syntax and how do i access the different
section from my script that loads the yaml file ?

First point: your second yaml file contains a mistake: you need to put a space
between the key of a hash and the value, so the second line should be

CVSEXE: "//foobar/c$/tools/cvsnt/cvs.exe"

(note the space after the :slight_smile:

To access more than one document in a yaml file, you should use
YAML.load_documents. It reads the data from a String or IO object, parses
each document and passes the result to the block. In your case, for example

File.open("config.yaml") do |f|
YAML.load_documents(f) do |d|
  p d
end
end

{"CVSEXE"=>"//foobar/c$/tools/cvsnt/cvs.exe"}
{"cvsrepos"=>["test", "test1", "foo", "bar", "foobar"]}

At any rate, I don't think you need to use two yaml documents for what you're
doing. Simply use a top-level hash, with keys CVSEXE and cvsrepos:

···

---
CVSEXE: "//foobar/c$/tools/cvsnt/cvs.exe"
cvsrepos:
- test
- test1
- foo
- bar
- foobar

YAML.load_file('config.yaml')
=> "CVSEXE"=>"//foobar/c$/tools/cvsnt/cvs.exe", "cvsrepos"=>["test", "test1", "foo", "bar", "foobar"]}

I hope this helps

Stefano

Hi,

···

-----Original Message-----
From: Stefano Crocco [mailto:stefano.crocco@alice.it]
Sent: Monday, March 12, 2007 1:08 PM
To: ruby-talk ML
Subject: Re: YAML.load_file problems

/*
First point: your second yaml file contains a mistake: you need to put a
space
between the key of a hash and the value, so the second line should be

CVSEXE: "//foobar/c$/tools/cvsnt/cvs.exe"

(note the space after the :slight_smile:
*/

thanks for the pointer !

/*
At any rate, I don't think you need to use two yaml documents for what
you're
doing. Simply use a top-level hash, with keys CVSEXE and cvsrepos:

---
CVSEXE: "//foobar/c$/tools/cvsnt/cvs.exe"
cvsrepos:
- test
- test1
- foo
- bar
- foobar

YAML.load_file('config.yaml')
=> "CVSEXE"=>"//foobar/c$/tools/cvsnt/cvs.exe", "cvsrepos"=>["test",
"test1", "foo", "bar", "foobar"]}
*/

yup that works in irb, but not in my script, i think the config.yaml
format is ok, but my access of
cvsrepos and CVSEXE is wrong =

require 'yaml'
require "highline/import"

YAML.load_file("config.yaml")

cvsuser = ask("Enter CVS User: ") {|q|
q.default = "#{ENV["USERNAME"]}"
q.echo = true}
cvspass = ask("Enter your password: ") { |q| q.echo = '*' }

cvsrepos.each {|x|
puts "Login CVS Repository >> #{x} ..."
IO.popen("#{CVSEXE} -d
:pserver:#{cvsuser}:#{cvspass}@cvsprod:d:/cvsrepos/#{x} login")
}
puts "Login successful !!"

and config.yaml

---
CVSEXE: "//foobar/c$/tools/cvsnt/cvs.exe"
cvsrepos:
- test
- test1
- foo
- bar
- foobar

the shell disappears right after the input of the password, without any
further (error)message.
Hm, any ideas what's wrong ? I thought YAML would be the recommended way
for
configfiles in ruby.

Or a simple alternative to yaml ?

Regards, Gilbert

Alle martedì 13 marzo 2007, Rebhan, Gilbert ha scritto:

the shell disappears right after the input of the password, without any
further (error)message.
Hm, any ideas what's wrong ? I thought YAML would be the recommended way
for
configfiles in ruby.

Or a simple alternative to yaml ?

YAML.load_file returns the contents of the yaml file in a hash or an array
(depending on the contents of the file, in your case is a hash). You need to
store the result somewhere, like this:

config=YAML.load_file('config.yaml)
...
config['cvsrepos'].each{ |x|
...
IO.popen("#{config['CVSEXE']} -d
...
}

Trying to access CVSEXE, which ruby thinks is a constant, without having
defined it, should rise a NameError exception, so I can't understand why you
don't get an error message.

I hope this helps

Stefano

Hi Stefano,

···

-----Original Message-----
From: Stefano Crocco [mailto:stefano.crocco@alice.it]
Sent: Tuesday, March 13, 2007 9:31 AM
To: ruby-talk ML
Subject: Re: YAML.load_file problems

/*

YAML.load_file returns the contents of the yaml file in a hash or an
array
(depending on the contents of the file, in your case is a hash). You
need to
store the result somewhere, like this:

config=YAML.load_file('config.yaml)
...
config['cvsrepos'].each{ |x|
...
IO.popen("#{config['CVSEXE']} -d
...
}

*/

works fine :slight_smile:
thanks

Regards, Gilbert