The order of iteration over hashes in Ruby 1.8 is undefined. For example, you do not know the order in which keys will return keys, or each yield pairs. ActiveSupport::OrderedHash implements a hash that preserves insertion order, as in Ruby 1.9:
oh = ActiveSupport::OrderedHash.new oh[:a] = 1 oh[:b] = 2 oh.keys # => [:a, :b], this order is guaranteed
ActiveSupport::OrderedHash is namespaced to prevent conflicts with other implementations.
Superclass of OrderedHash
Note that in Rails 2.3, OrderedHash changed from being a subclass of Array to a subclass of Hash. This is contrary to what the documentation says above.
is now a subclass of Hash that preserves order (or _is_ a Hash if running Ruby 1.9 or greater)
You might not realize it preserves order because it delegates inspect to its super-class, Hash, which doesn’t preserve order. But you will see that order is preserved if you iterate or use the keys or values methods:
>> names = ['Amy Irving', 'Jane Doe', 'John Doe', 'John Updike', 'Susan Anthony'] >> ordered = names.group_by { |name| name.split.first } => #<OrderedHash {"John"=>["John Doe", "John Updike"], "Amy"=>["Amy Irving"], "Susan"=>["Susan Anthony"], "Jane"=>["Jane Doe"]}> # (note that the inspect above is in undefined order) >> ordered.keys # will be ordered properly => ["Amy", "Jane", "John", "Susan"] >> ordered.each { |first, full| puts first; full.each { |name| puts " #{name}" } } # will be ordered properly Amy Amy Irving Jane Jane Doe John John Doe John Updike Susan Susan Anthony