is Rails3 sorting Hashes?

Hi,

does rails3 automatically sort hashes by their keys? I was trying to ensure for a model, that a location saved in a (mongoid) hash is always :location => {:lat => Float, :lng => Float}. So I wrote a test that should fail when I give it :location => {:lng => Float, :lat => Float} instead, but it doesn't. When I expected the output, it was in fact in the correct (lat before lng) order.

If rails3 performs this sorting, can I always rely on that?

cheers, Dennis

http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/

Robert Pankowecki

Hi,

does rails3 automatically sort hashes by their keys? I was trying to ensure for a model, that a location saved in a (mongoid) hash is always :location => {:lat => Float, :lng => Float}. So I wrote a test that should fail when I give it :location => {:lng => Float, :lat => Float} instead, but it doesn't. When I expected the output, it was in fact in the correct (lat before lng) order.

If rails3 performs this sorting, can I always rely on that?

Whether hashes preserve order is down to whether you are running ruby 1.9 or not. Further more, the ordering is the order in which the keys are inserted. However, equality is a slightly different matter :location => {:lat => Float, :lng => Float} is equal to :location => {:lng => Float, :lat => Float} since two hashes are equal if they have the same key value pairs (ordering is not considered)

Fred

Dennis Schmidt wrote in post #975084:

does rails3 automatically sort hashes by their keys? I was trying to ensure for a model, that a location saved in a (mongoid) hash is always :location => {:lat => Float, :lng => Float}. So I wrote a test that should fail when I give it :location => {:lng => Float, :lat => Float} instead, but it doesn't. When I expected the output, it was in fact in the correct (lat before lng) order.

If rails3 performs this sorting, can I always rely on that?

Simple answer assuming Ruby 1.9; yes you can rely on the order of the key-value pairs.

Slightly move complex answer; no you should not rely on the order of key-value pairs in hashes.

There are, however, some interesting use cases for reliance on order hashes. For example if you wanted an ordered list of the keys for presenting in drop-down list you could save having to sort them.

If you really wanted to rely on argument positioning for lat and lgn you could do something like :location => [Float, Float]. Unlike Hashes Ruby Arrays are guaranteed to be ordered no matter what version of Ruby you're using.

Frankly, I don't see why you care. Getting location[:lat] and location[:lng] is going to get you the correct values no matter what order the hash stores them. That kinda the point of a Hash is it not?