Ruby continues to impress me. I don't think I've written a Perl script in a year. I really love the way it handles attributes. That's why I've come to appreciate OpenStruct. This handy class allows you to essentially create data structures on the fly.

I've also come to really love YAML as a way to represent data structures. I find it more visually appealing and easier to edit than XML. Since Ruby has a built in YAML parser, this is a match made in heaven. My one beef is that accessing nested data is a bit of a pain. Say, we have the following YAML:

invoice_number: 34843
date: 2001-01-23 00:00:00 -0600
products:
  - sku         : BL394D
    quantity    : 4
    description : Basketball
    price       : 450.00
  - sku         : BL4438H
    quantity    : 1
    description : Super Hoop
    price       : 2392.00

Accessing the first product's SKU, requires the following code:

>> invoice = YAML.load_file("invoice.yml")
>> invoice["products"].first["sku"]
=> "BL394D"

Wouldn't it be great if you could access it like:

>> invoice.products.first.sku
=> "BL394D"

Well, now you can. I've created a function called hashes2ostruct that recursively converts all hashes to OpenStructs. As seems to be common with Ruby, it's not a whole of code:

require 'ostruct'

def hashes2ostruct(object)
  return case object
  when Hash
    object = object.clone
    object.each do |key, value|
      object[key] = hashes2ostruct(value)
    end
    OpenStruct.new(object)
  when Array
    object = object.clone
    object.map! { |i| hashes2ostruct(i) }
  else
    object
  end
end

Now you can easily convert the hashes from YAML:

>> invoice = hashes2ostruct(YAML.load_file("invoice.yml"))
>> invoice.products.first.sku
=> "BL394D"

It also works if the top level object is an array. I've been using this code for a while, in some form or another, but figured it would be nice to share.