ya config file parser

R

Roberto Cm

I'm wondering how to extend the config-yaml parser at
http://www.mjijackson.com/2010/02/flexible-ruby-config-objects so I can
write to the file through the variable.

right now it works like this:

yaml_data = "
---
database: mydb
auth:
user: myuser
pass: mypass
"

require 'yaml'
config = Config.new(YAML.load(yaml_data))

config.auth.user # "myuser"


and I want to add some magic so I can do this instead:

config = Config.new(yaml_filename_variable)
config.a = "test"
p config.a
=> "test"
config.write()
config = nil
config = Config.new(yaml_filename_variable)
p config-a
=> "test"


to load the file on new(), I changed the class like this:

require 'yaml'

class ConfigYaml

def initialize(file)
if file.nil?? then
yaml_conf = YAML.load_file(file)
end
@data = case yaml_conf.nil?
when true then YAML.load_file(file)
else {}
end
update!(data)
end

private
...
 
B

Brian Candler

Roberto said:
to load the file on new(), I changed the class like this:

require 'yaml'

class ConfigYaml

def initialize(file)
if file.nil?? then
yaml_conf = YAML.load_file(file)
end
@data = case yaml_conf.nil?
when true then YAML.load_file(file)
else {}
end
update!(data)
end

That looks a bit broken - 'data' is a local variable or method, which
you don't seem to have, which is different from @data which is an
instance variable.

You could try this as a starting point:

class ConfigYaml
def initialize(file)
@filename = file
load
end

def load
@data = YAML.load_file(@filename)
rescue Errno::ENOENT
@data = {}
end

def save
File.open(@filename,"w") { |f| f.write YAML.dump(@data) }
end

... rest as before
end
 
R

Roberto Cm

Brian said:
That looks a bit broken - 'data' is a local variable or method, which
you don't seem to have, which is different from @data which is an
instance variable.

yea it's a typo. Thanks for the rescue though! --
rescue Errno::ENOENT

-- The problem with the save method is .. well actually nothing, I need
that too :) But I want to not have to explicitly call save, and instead
have the object detect changes and behave dynamically -- ie, assignment
to the config instance should write directly to disk as well as to the
attribute during the set_x methods.

But how do I change setter methods that don't exist yet?
 
B

Brian Candler

Roberto said:
-- The problem with the save method is .. well actually nothing, I need
that too :) But I want to not have to explicitly call save, and instead
have the object detect changes and behave dynamically -- ie, assignment
to the config instance should write directly to disk as well as to the
attribute during the set_x methods.

But how do I change setter methods that don't exist yet?

I don't see what you mean. You are defining the []= method yourself, so
you can make it do whatever you like, including call 'save'. It doesn't
matter if you define the []= method first, or the save method first.
What matters is whether the method exists *at the time it is called*.

If you are subclassing you can use super:

class AutoSaveConfig < ConfigYAML
def []=(*args)
super
save
end
end

If you are monkey-patching (overriding code in an existing class without
modifying the original source file) you can use alias:

class ConfigYAML
alias :eek:ld_set :[]=
def []=(*args)
old_set(*args)
save
end
end

Note: the class name "Config" (in the original code) is not a good
choice, because Ruby has its own Config class, commonly used when
building extensions.

require 'rbconfig'
puts Config::CONFIG['libdir']
 

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
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top