Hacker News new | comments | show | ask | jobs | submit login
Ruby 1.9 Internals: Ordered Hash (igvita.com)
48 points by igrigorik 2793 days ago | hide | past | web | 11 comments | favorite

A few random thoughts about Ruby's traditional unordered Hash:

The Hash#keys method should have returned a Set, not an Array. That way no one would have been baffled by the lack of predictable order. But, unfortunately, Set is not a built-in class. Hence, Hash#keys has to return an Array.

Since Rails came out, there's been, I think, an ever increasing use of Symbols as Hash keys. If you want to examine your Hash in a specific order--perhaps in a test--it's tempting to sort the Array of keys. But there's no Symbol#<=> method. Therefore, an Array of Symbols cannot be sorted (without monkey patching).

If, for whatever reason, you create a Hash whose keys are of various types, the keys are probably not sortable. Hence, there's no way to examine its contents in a predictable order.

A few thoughts about the new ordered Hash:

Personally, I see no need for the built-in Hash to be ordered. I'm so accustomed to thinking of hashes as unordered. And, because I don't have Ruby 1.9, I don't use the newfangled hashy syntax for passing parameters.

But one of the commenters (Radarek) points out something about parameter passing. He/she says, "It's another big + for ordered hashes because they are used as replacement for named parameters [in Ruby 1.9]." He/she mentions a project in which a method must process its keyword parameters in the order they were given.

The thought of trying to process keyword parameters in the order given is very jarring to my old-fashioned Ruby brain, and to my Python brain. Yet, evidently, someone out there wants to do this without telling the client to pass an Array of Arrays.

So I wonder what the major use case is for the predictable ordering of the built-in Hash. Perhaps it's for ease of examining and comparing Hashes in tests? Perhaps it's for processing keyword parameters in a specific order when they're passed using spiffy syntax? What?

Man, who doesn't need an ordered hash from time-to-time?

The big problem is that most people assume a hash isn't ordered -- so when looking at Ruby source, I wonder if this is going to be confusing for awhile?

Shouldn't be too bad. After all, it's a strict superset of the functionality of the old hash. The only confusion will come when someone looks at some code and notices, "Hey, shouldn't this be an ordered hash?" Then they go google "ruby ordered hash" and this blog post pops up and problem solved.

Basically it'd be nice if you could distinguish between instances where iteration order is important and not important. A separate datatype would do that (at the expense of other things, obviously)

If you're worried about it in your app, you could always do

  class OHash < Hash ; end
And use OHash as a marker that you're taking advantage of the ordering features.

Over time, though, I think this will be a real plus for people learning programming via Ruby. Non-ordered hashes are non-intuitive if you don't know what "hash" means, and think it's just a dictionary.

There are times when I thought this would be useful, so its nice to see. Interesting to see how the implementation is done.

Nice to see that its actually faster too!

The only time I've ever felt like I really needed this so far was when dumping out a large hash to YAML to save as seed data. YAML at one point had support for ordering hashes but it went unmaintained for so long that although it was part of the API and was in the documentation, it simply didn't work. I haven't checked yet but I would assume it should work now in 1.9.

Having an ordered hash is ruby is very useful. I've been using ActiveSupport::OrderedHash with ruby 1.8.7.

I've been really looking forward to this mostly because of how bad ActiveSupport's implementation of this is. For instance, lookups require a linear scan. Definitely a welcome change.

Why is the doubly linked list circular?

Probably to simplify the add/remove code and life in general.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact