Drying Out Your Crack
A Little Powder Goes a Long Way
Look, I spend a lot of time commuting a couple of times a week into downtown DC via the ‘fine’ public transportation system here. There is no doubt that during these hot summer months, while standing ‘nuts to butt’ with my fellow commuters in a metro car packed like sardines, sweating buckets. It’s an uncomfortable feeling to put it mildly. Which brings me to my point, and that is-sometimes code imitates life. To be honest, I spend the majority of my time during my commute reviewing code, which is oftentimes my own.

On to the Real Show
I know, I know, lame blog bait. Ok, fair enough. But I promise the title really makes sense within the context of what I want to talk about. So I’m on the train today reviewing some code I’ve been working on here and there over the last week. It’s a Ruby gem that provides an abstraction to a REST API provided by my current client as part of the data.gov initiative. This particular API uses an XMsmeLs, also know as XML, protocol for interacting with its resources. Needing a way to parse and deal with XML, I took a look around at the available gems in the wild. Nokogiri looked awesome, but it was more that what I needed. I ended up using the Crack gem which, from what I gathered, had a lot of fans in the Ruby community.
Crack
Crack is a XML and JSON parsing gem. Actually, it is a simple XML to Hash marshaling framework that is shamelessly a copy and paste job from source found in both Merb and Rails. The gist is feed Crack, an XML document, and it provides you with a Hash representation of that document. This is great, because a Hash can easily and quite naturally represent hierarchical data.
xml = Crack::XML.parse("<foo><bar><baz>contents</baz></bar></foo>")
=> {"foo"=>{"bar"=>{"baz"=>"contents"}}}
puts xml['foo']['bar']['baz']
=> "contents"
Awesome, this is a straight forward and an easy way to deal with (dreadful) XML. So I moved forward with it and wrote a lot of code using this nested Hash key style even though it always made me feel a little ‘dirty’. So this morning at 6:30am while on the train with 300 of my closest friends I revisited this code and had the same ‘dirty’ feeling. So I decided to do something about it.
My first inclination was that I needed a nice way to navigate the document using attribute-like ‘.’ notation. Attribute access just feels better since there is less syntactic noise and it is just as expressive as doing Hash navigation. So I knew what I wanted about half way through my 1 1/2 hour-long commute. Unfortunately, the data service was pretty spotty because the train snakes its way underground into the nation’s capital. Luckily, as the train entered into Metro Center Station, I got a signal and hit the Googs with a search for “recursive openstruct”. Bam! Once again Google provided me with exactly what I was looking for to “dry” out this Crack.
“Drying Out Your Crack” with Recursive Open Struct
Ruby’s stdlib OpenStruct class gives a nice abstraction (syntactic sweetener) to Hashes. It’s weakness is that it only supports a single level of abstraction.
better = OpenStruct.new({"foo"=>{"bar"=>{"baz"=>"contents"}}})
=> #<OpenStruct foo={"bar"=>{"baz"=>"contents"}}>
puts better.foo
=> {"bar"=>{"baz"=>"contents"}}
Better, but foo is a Hash, and therefore I obviously can’t navigate to better.foo.bar, which is the goal. Enter the recursive open struct gem/class, which does exactly what the name suggests.
mo_better = RecursiveOpenStruct.new({"foo"=>{"bar"=>{"baz"=>"contents"}}})
=> #<RecursiveOpenStruct foo={"bar"=>{"baz"=>"contents"}}>
looks similar but thanks to Ruby’s ability to dynamically define methods, this now works
puts mo_better.foo.bar.baz
=> "contents"
Now that is “Mo Better”. Mission accomplished.
Summary
I wouldn’t use Crack if the XML documents that I was dealing were large, and required XPath to effectively navigate. Nokogiri would be a much more appropriate tool to use. But for my particular case, the documents that I had to deal with made Crack a nice fit. I’m not sure if there is a rule about Hash depth, but to me Hash navigation higher than two starts to make the code smell. RecursiveOpenStruct gave me the syntactic style I was looking for and dried out my Crack quite well. Now I need to find some talcum power to dry out my other problem.