
-----------------------------------
wtd
Sat Mar 26, 2005 11:57 pm

Quickly and Easily Storing Data
-----------------------------------
The Problem

We have some data in a program and we need to store it in a file so we can get at it later.

Solutions

Well, we could cook up our own solution.  In the Turing forums I've seen this so many times it boggles the mind.  But the problem with that is that everyone comes up with their own half-baked solution and no one can use anyone else's datafiles in their own programs.

How about a common, standardized data format?

Enter XML.  But, there's a problem with XML.  It's big.  Let's look at a possible representation of an array in XML.


   42
   "hello"


Considering how little data's in there that's an awful lot of text.  XML is highly customizable, and there are times when that's valuable, but it lacks convenient, lightweight and standard syntax for the most common types of data.

So, what are we left with?  

Perhaps the most appealing option remaining is YAML.  Yet Another Markup Language is just what we're looking for.  Let's look at the previous example in YAML.

- 42
- hello

Or even more simply:

[42, hello]

We Have a Winner!  Now What?

YAML is not exclusive to Ruby, but has enjoyed a high degree of popularity within the Ruby community due to the excellent support of the YAML library for Ruby.  

This library is included standard with Ruby 1.8.  If you have a packaged Ruby other than the standard (for instance, the Ubuntu version of Ruby 1.8 is slightly nonstandard) you may need to separately install the YAML library.

Bringing the YAML library into play is a simple matter of including the following lines.

require 'yaml'

include YAML

Now, to convert a data structure to YAML we need a data structure.  Let's try something like the following.

info = [
   {
      "name" => {"first" => "Bob", "last"  => "Smith"}, 
      "car"  => {"make"  => "AMC", "model" => "Gremlin"}
   },
   {
      "name" => {"first" => "John", "last"  => "Doe"}, 
      "car"  => {"make"  => "Ford", "model" => "Escort"}
   }
]

Now, we can get the equivalent YAML as easily as:

info.to_yaml

And it looks like:

---
-
  name:
    last: Smith
    first: Bob
  car:
    make: AMC
    model: Gremlin
-
  name:
    last: Doe
    first: John
  car:
    make: Ford
    model: Escort

Now, if I want to save this to a file, I need only open a file for writing and print it.

File::open "datafile.dat", "w" do |f|
   f.puts info.to_yaml
end

But, what about getting that information back?

info = YAML::load(File::open("datafile.dat").read)

Questions?

Any questions?  Further information about using YAML that you'd like?

-----------------------------------
jamonathin
Thu Mar 31, 2005 9:45 am


-----------------------------------
wtd, you're crazy man, how do you know all this stuff!  Madness i say. 

     Since regular bits don't mean anything to you . . +  :D Bits.

-----------------------------------
Tony
Thu Mar 31, 2005 12:52 pm


-----------------------------------
YAML is awesome. It came in really handy in the project I was working on when I read the tutorial. Score.

What I would like to see is a tutorial on the use of hashes.

-----------------------------------
Hikaru79
Sat Apr 02, 2005 8:44 pm

Re: Quickly and Easily Storing Data
-----------------------------------

Perhaps the most appealing option remaining is YAML.  Yet Another Markup Language is just what we're looking for.  Let's look at the previous example in YAML.


I thought YAML = "YAML Ain't a Markup Language"? (A la "GNU Ain't UNIX")

-----------------------------------
wtd
Sat Apr 02, 2005 8:57 pm

Re: Quickly and Easily Storing Data
-----------------------------------

Perhaps the most appealing option remaining is YAML.  Yet Another Markup Language is just what we're looking for.  Let's look at the previous example in YAML.


I thought YAML = "YAML Ain't a Markup Language"? (A la "GNU Ain't UNIX")

D'oh!

-----------------------------------
Thuged_Out_G
Mon Apr 24, 2006 7:01 pm


-----------------------------------
Ok, so we have info, which contains all that info. How can you pick it apart, to store the users first name in 'first_name' and so on

or is there a way to do something like:
puts info.first_name

-----------------------------------
Cervantes
Mon Apr 24, 2006 7:25 pm


-----------------------------------
Well, info is an array. So if we're looking at the first person in the array, we use
info[0]
or better yet
info.first
Now, info.first is a hash. We're interested in names, so we'll do
info.first["name"]
Now, info.first is also a hash. We're interested in first names, so we'll do
info.first["name"]["first"]
This gives us the first name for the first person in the array, info; it gives us "Bob".
