From: Trans Date: 2008-10-26T21:53:40+09:00 Subject: Re: Hash.merge_add! extension - how does this code look? On Oct 26, 7:20 am, "Greg Hauptmann" wrote: > Hi, > I wanted a way to be able to "add" values to a Hash such that it keeps the > old and the new values.  For examples example adding an item to a hash for > which the keys are dates.   Here's a first cut.  Any feedback on coding > style etc? > > ================================ > class Hash >   # Merges a hash with only one item into your hash.  If there is already a >   # hash entry for that key the both existing value(s) & new value are kept > via >   # use of an Array >   def merge_add!(h) >     raise "Parameter passed in not a hash" if !h.instance_of?(Hash) You don't need to do this. It is "anti-ducktyping". h could be a hash- *like* object and that would be okay. >     raise "Can only pass hash with one item to be added" if h.length > 1 Why artificially limit it to one entry hashes? Supporting any hash would make it more flexible. >     h_key = h.to_a[0][0] >     h_value = h.to_a[0][1] >     if self.has_key?(h_key) >       existing_value = self[h_key] >       existing_value_as_array = existing_value.instance_of?(Array) ? > existing_value : [existing_value] >       new_value = existing_value_as_array << h_value >       self[h_key] = new_value >     else >       h_value.instance_of?(Array) ? self.merge!(h) : self.merge!( {h_key => > [h_value]} ) >     end >   end > end The idea is a good one. I think implementation could use some improvement. For comparison have a look at Facets' Hash#collate. http://facets.rubyforge.org/doc/api/core/classes/Hash.html#M000112 t