YAML to objects - how?

B

Bill Guindon

I'm trying to read in a YAML file that has a list of database specs
(name, fields, indexes, etc.) Once that's read in, I'd like to turn
them into an array of db objects. In the end, I want to loop through
the array and generate some code based on each database spec.

Is there an easy way to do this?

I've been staring at: http://whytheluckystiff.net/ruby/yaml-defaults-mixin.rb

It seems to be about the only thing I can find that discusses
object_maker and add_domain_type which seem relevant, but may very
well have nothing to do with what I'm after.

Any suggestions? Should I point out that I've never done anything
with YAML, or is that obvious by now?

thx in advance.
 
J

Joel VanderWerf

Bill said:
I'm trying to read in a YAML file that has a list of database specs
(name, fields, indexes, etc.) Once that's read in, I'd like to turn
them into an array of db objects. In the end, I want to loop through
the array and generate some code based on each database spec.

Is the YAML file something like this?

---
-
name: Foo
fields:
- :x
- :y
- :z
indexes:
-
name: Bar
fields:
- :a
- :b
- :c
indexes:

If so, then you can just YAML.load() the file, and you'll get an array
of hashes, which you can iterate over.
 
B

Bill Guindon

Is the YAML file something like this?

---
-
name: Foo
fields:
- :x
- :y
- :z
indexes:
-
name: Bar
fields:
- :a
- :b
- :c
indexes:

Pretty close (should've included it)
Do I need the colons before the field names? I'm not doing that now.

Here's a couple table's worth:
---
-
name: PM_Static_SettingsDB
file: settings.dbf
fdel: false
dnoc: false
fields:
- key CHAR 254
- redir CHAR 254
- admin CHAR 254
- hidehelp BOOL
- last_tab CHAR 50

indexes:
-
file: cats.mvx
expr: PM_Static_catsDB.d.cat_id
flag: nounique, ascending
-
name: PM_Static_KeysDB
file: keys.dbf
fdel: false
dnoc: true

fields:
- name CHAR 50
- value NUMBER
indexes:
-
file: keys.mvx
expr: PM_Static_KeysDB.d.name
flag: nounique, ascending

If so, then you can just YAML.load() the file, and you'll get an array
of hashes, which you can iterate over.

I'll give that a shot, was wondering if there was a way to auto create
objects from the YAML load, but yeah, I could loop through them and do
it that way. I'll see how it goes.
 
J

Joel VanderWerf

Bill said:
Do I need the colons before the field names? I'm not doing that now.

Oh, not at all. I just did that because I tend to use symbols rather
than strings when I am describing attr_accessors and the like. But you
can use strings for better readability in the yaml file.
I'll give that a shot, was wondering if there was a way to auto create
objects from the YAML load, but yeah, I could loop through them and do
it that way. I'll see how it goes.

If you want to autocreate, you can use the syntax for defining the class
of objects, but the YAML file will look messier. You can see how it will
look by creating some objects in ruby code, and them calling #to_yaml on
them. F'rexample:

require 'yaml'

class C
attr_accessor :x
end

c = C.new
c.x = {:foo => ["bar"] }

puts c.to_yaml

The output is

--- !ruby/object:C
x:
:foo:
- bar

If you YAML.load this, it will create an instance of C.

Alternately maybe there is some hook in the YAML parser that lets you
say "instantiate all hashes with objects of class C", but that seems
problematic if you use hashes elsewhere in the data.

Another option is to extend the YAML parser to recognize some custom
types that have less cumbersome syntax than "!ruby/object:YourClass".
You can find examples in yaml/types.rb in your ruby lib dir.
 
B

Bill Guindon

Bill said:
Do I need the colons before the field names? I'm not doing that now.

Oh, not at all. I just did that because I tend to use symbols rather
than strings when I am describing attr_accessors and the like. But you
can use strings for better readability in the yaml file.
I'll give that a shot, was wondering if there was a way to auto create
objects from the YAML load, but yeah, I could loop through them and do
it that way. I'll see how it goes.

If you want to autocreate, you can use the syntax for defining the class
of objects, but the YAML file will look messier. You can see how it will
look by creating some objects in ruby code, and them calling #to_yaml on
them. F'rexample:

require 'yaml'

class C
attr_accessor :x
end

c = C.new
c.x = {:foo => ["bar"] }

puts c.to_yaml

The output is

--- !ruby/object:C
x:
:foo:
- bar

If you YAML.load this, it will create an instance of C.

Alternately maybe there is some hook in the YAML parser that lets you
say "instantiate all hashes with objects of class C", but that seems
problematic if you use hashes elsewhere in the data.

Another option is to extend the YAML parser to recognize some custom
types that have less cumbersome syntax than "!ruby/object:YourClass".
You can find examples in yaml/types.rb in your ruby lib dir.

I ended up going with your first suggestion (after getting a slightly
firmer grasp of YAML). The alternatives seem to carry too high a
price for "auto" object creation.

In the long term, I hope that changes, in the short term, looping
through what I have will work fine.

Thx for you input.
 

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

Similar Threads

String to YAML to Hash 1
What is YAML::Syck::Map? 1
YAML and NArray 1
yaml, erb, and behavior trees 0
using YAML as config 13
YAML + ASCII Encoded Unicode 1
Importing from YAML 6
YAML Parsing, ignoring objects? 4

Members online

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,459
Latest member
Vida00R129

Latest Threads

Top