Beginner: Options with YAML

O

Oliver Cromm

I already use YAML to handle persistance of a queue, e.g. - one big data
structure.

But I don't understand how to use it for many independent values,
something like Options.

So I have a script with these settings (currently as Constants in the
script)

SERVER = news.example.org
PORT = 100
USER = myname
PASS = topsecret

How do I put this in a YAML file and load it into my Ruby script? All
ways I can think of are clumsy. Or shouldn't I?

Your help is greatly appreciated. All documentation I saw is too
abstract and didn't help me for that. A single usage example might have
saved me an hour of searching and reading already ...
 
J

James Edward Gray II

I already use YAML to handle persistance of a queue, e.g. - one big
data
structure.

But I don't understand how to use it for many independent values,
something like Options.

So I have a script with these settings (currently as Constants in the
script)

SERVER = news.example.org
PORT = 100
USER = myname
PASS = topsecret

How do I put this in a YAML file and load it into my Ruby script? All
ways I can think of are clumsy. Or shouldn't I?

The first thought that pops into my head is to store these options in
a Hash, then YAML that back and forth.

If you're really attached to the constants though, write a method
that finds them via reflection, builds the Hash, and YAML stores it.
Then write another method to reverse the process. Shout if you get
stuck on any of that and I will help...

James Edward Gray II
 
S

Stefan Lang

I already use YAML to handle persistance of a queue, e.g. - one big
data structure.

But I don't understand how to use it for many independent values,
something like Options.

So I have a script with these settings (currently as Constants in
the script)

SERVER = news.example.org
PORT = 100
USER = myname
PASS = topsecret

How do I put this in a YAML file and load it into my Ruby script?
All ways I can think of are clumsy. Or shouldn't I?

One possible solution:
Simply store the information in a hash in a yaml file.
E.g. /home/user/.myapp.config could contain:

SERVER: news.example.org
PORT: 100
USER: myname
PASS: topsecret

Ruby code to load the settings:

require 'yaml'
CONFIG = YAML.load_file(File.join(ENV["HOME"], ".myapp.config"))
puts "Server: #{CONFIG["SERVER"]}"
puts "Server: #{CONFIG["PORT"]}"
...

HTH,
Stefan
 
O

Oliver Cromm

* James Edward Gray II said:
The first thought that pops into my head is to store these options in
a Hash, then YAML that back and forth.

Well, by 'clumsy' I meant exactly something like

| login(Options['server'], Options['port'], Options['user'], Options['pass'])

and so on throughout the script.
If you're really attached to the constants though, write a method
that finds them via reflection, builds the Hash, and YAML stores it.
Then write another method to reverse the process. Shout if you get
stuck on any of that and I will help...

I don't know what reflection means in this context, but am I guessing
right that we are talking about something (maybe something more elegant)
that has the same *effect* as:

def getOptions
Options = YAML.load_file(OPTFILE)
SERVER = Options['server']
PORT = Options['port']
...
end
 
J

James Edward Gray II

Well, by 'clumsy' I meant exactly something like

| login(Options['server'], Options['port'], Options['user'],
Options['pass'])

and so on throughout the script.

Hmm, I don't see that as significantly different from:

login(SERVER, PORT, USER, PASS)

Though I will concede that it's a little shorter.

I would probably pass some kind of options object into the method and
query it from inside:

#!/usr/local/bin/ruby -w

require "ostruct"
require "yaml"

def open_connection( connection )
p connection.server
end

if File.exists? "config.yaml"
config = File.open("config.yaml") { |file| YAML.load(file) }

open_connection(config)
else
config = OpenStruct.new( :server => "news.example.org",
:port => 100,
:user => "myname",
:pass => "topsecret" )

File.open("config.yaml", "w") { |file| YAML.dump(config, file) }
end

__END__

Even better, perhaps a Connection object could manage its own data,
and then you could just YAML it back and forth, or something similar.
I don't know what reflection means in this context, but am I guessing
right that we are talking about something (maybe something more
elegant)
that has the same *effect* as:

def getOptions
Options = YAML.load_file(OPTFILE)
SERVER = Options['server']
PORT = Options['port']
...
end

Here's what I basically had in mind:

#!/usr/local/bin/ruby -w

require "yaml"

$standard_constants = Module.constants

def save_config
config = Hash.new
(Module.constants - $standard_constants).each do |const|
config[const] = Module.const_get(const)
end

File.open("config.yaml", "w") { |file| YAML.dump(config, file) }
end

def load_config
config = File.open("config.yaml") { |file| YAML.load(file) }

config.each_pair do |const, value|
Object.const_set(const, value)
end
end

if File.exists? "config.yaml"
load_config
p SERVER
else
SERVER = "news.example.org"
PORT = 100
USER = "myname"
PASS = "topsecret"

save_config
end

__END__

Hopefully this gives you some fresh ideas.

James Edward Gray II
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,182
Messages
2,570,959
Members
47,509
Latest member
Jack116

Latest Threads

Top