Something like this (hoping GG doesn't mess up the indenting): # Assumes you're not initializing with values at the beginning, i.e. # h = InsertOrderHash.new # Extension to the general case is left as an exercise for the reader # (I've always wanted to say that ;-) class InsertOrderHash < Hash def initialize(*args) @insert_order = Array.new end def []=(key, val) @insert_order.push key unless self.key? key super end def each # Assumes block follows @insert_order.each do |key| yield key, self[key] end end