Hashes to OpenStruct

|

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

blog comments powered by Disqus

About this Entry

This page contains a single entry by Dave published on November 17, 2006 9:47 AM.

Announcing MAME OS X was the previous entry in this blog.

Fast InvSqrt()? Only if you GPL! is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Links

Powered by Movable Type 4.1