I !(heart) Rails

Ruby on Rails does some nifty things, trying to lull you into a false sense of submission - and then it springs this on you. For those unfamiliar with the glory and the horror that is RoR, let me enlighten you...

Rails can parse incoming XML and hand it to you as a Hash. Makes sense. XML's inherently hierarchial, so it maps nicely to a key/value container. There's just one pesky little detail: How to handle Elements vs. Attributes, e.g.

<Person Name="Howard">Howard</Person>

Usually not a problem, as they're somewhat equivalent structurally (loosely speaking) and either could be used (there's long-running discussions on Attributes vs. Elements for data processing; Bing for them). But what if they're both present? Not a common practical issue; simple design tends to avoid such ambiguities (or if you prefer complex design, there's always XML Namespaces :-). So Rails can turn your incoming HTTP Request body's XML into a Hash lickety split.

Notably, JSON doesn't suffer from this malady, having been designed for data from day one and not stolenderived from the document publishing community. But one of a myriad of reasons to prefer JSON over XML for data processing.

But I digress... We were speaking of Rails the wunderkind, and how it conveniently turns XML into a parsed Hash.

Except when it horks it up.

xml = ‘<I Hate=”Rails”>Duh</I>’

puts Hash.from_xml(xml).inspect

Guess what you get?


Right about now you're asking yourself, where's the Hate? 

If you have an Element with Attribute(s) and just a child #text node, Hash.from_xml drops the attributes.

Yes. Really.

Rails 2.3.2. You know. The version released in 2009.

But try this

argh='<I Hate="Rails"><Foo>bar</Foo></I>'

puts Hash.from_xml(argh).inspect

and you get

{"i"=>{"foo"=>"bar", "hate"=>"Rails"}}

Element with 1+ Attribute, 0 child Element and 1(+?) child #text node and Rails goes off the rails into whacko jacko land.

Yet another example why Rails feels strongly suited for small consulting shops but still nowhere near ready for serious or large scale development.

[Yes, I know there's plenty of shops and sites and folks who can 'disprove' that statement. They're still wrong. Stability. Compatbility. Reliability. Why do you gleefully offer to sacrifice these on the alter of false productivity? Ruby? Thank you, but I'd prefer not to.

Java? C#? Puh-leaze. Still not quite in the same league as Python 🙂

[Though C#'s getting about as sanely close as you'd want to. C# 4.0 and IronPython - now there's a match to keep your eye on...]

Comments (2)

  1. Garry Trinder says:

    I think th ereal problem is that your initial premise ("XML’s inherently hierarchial, so it maps nicely to a key/value container. ") is wrong.

    XML hierarchy is 3-dimensional, while key/value container is inherently 2-dimensional.   One does not map nicely into the other.

  2. howardk says:

    That’s the crux of the issue. Though it’s more accurate to say XML has 2 planes of hierarchial data (Elements and Attributes) which *can* map to 1 plane of hierarcial data (OO). As you say, XML doesn’t map nicely to 1-planar data structures.

    But that wasn’t my core premise. It’s just a truism.

    My core premise is, neither XML, Ruby, Rails or Ruby’s Hash class are new technologies. My core premise is it’s shocking it’s handled so poorly.

    I could understand not handling Attributes at all (problem solved). I could understand treating attributes and elements equivalently, and blindly ignoring any collisions (last one parsed wins) – or just dictating one or the other wins in case of collision. I could understand glomming all attributes into a specifically named bucket (e.g. ‘__attributes__’=>{…}).

    What I can’t understand is the patchy inconsistency to how it’s handled. It has the feel of something hacked together in an overnight rushed session. Quick and dirty hacks have their place, but tools and architectures rarely surivive and thrive w/o a bit more consideration and completeness.

    For an oversimplification, if Java is the ‘overengineered’ ecosystem, Rails is its polar opposite. Can’t we meet somewhere in the middle?

    [Well, yes, we can. It’s called Python. But I digress… :-]

Skip to main content