# Ya config file parser

**URL:** <https://www.ruby-forum.com/t/ya-config-file-parser/187208>\
**Category:** Ruby\
**Created:** [April 19, 2010, 8:23pm UTC](https://www.ruby-forum.com/t/ya-config-file-parser/187208 "2010-04-19T20:23:55Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![robyonrails](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@robyonrails](https://www.ruby-forum.com/u/robyonrails)\
**Post date:** [April 19, 2010, 8:23pm UTC](https://www.ruby-forum.com/t/ya-config-file-parser/187208/1 "2010-04-19T20:23:55Z")

</div>

I’m wondering how to extend the config-yaml parser at  
[Deneme Bonusu Veren Bahis Siteleri - En iyi Bonus Veren Siteler Nelerdir?](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  
…

---

<div class="post-metadata">

**Author:** ![robyonrails](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@robyonrails](https://www.ruby-forum.com/u/robyonrails)\
**Post date:** [April 19, 2010, 10:44pm UTC](https://www.ruby-forum.com/t/ya-config-file-parser/187208/2 "2010-04-19T22:44:01Z")

</div>

Roberto Cm wrote:

> 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

---

<div class="post-metadata">

**Author:** ![robyonrails](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@robyonrails](https://www.ruby-forum.com/u/robyonrails)\
**Post date:** [April 20, 2010, 12:23am UTC](https://www.ruby-forum.com/t/ya-config-file-parser/187208/3 "2010-04-20T00:23:30Z")

</div>

Brian C. wrote:

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

---

<div class="post-metadata">

**Author:** ![robyonrails](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@robyonrails](https://www.ruby-forum.com/u/robyonrails)\
**Post date:** [April 20, 2010, 12:32pm UTC](https://www.ruby-forum.com/t/ya-config-file-parser/187208/4 "2010-04-20T12:32:43Z")

</div>

Roberto Cm wrote:

> – 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 :old\_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’]
