From: Greg Hauptmann Date: 2008-10-26T20:20:02+09:00 Subject: Hash.merge_add! extension - how does this code look? ------=_Part_5835_2746402.1225020018466 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline 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) raise "Can only pass hash with one item to be added" if h.length > 1 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 ================================ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "merge_add!" do before(:each) do @empty_hash = {} @hash_with_number = {100 => 1} @hash_with_array = {100 => [1]} end it "should raise an error if there is no object passed to the method" do lambda{ @empty_hash.merge_add!() }.should raise_error(ArgumentError) end it "should raise an error if the object passed is not a Hash" do lambda{@empty_hash.merge_add!(123)}.should raise_error(RuntimeError, "Parameter passed in not a hash") end it "should raise an error if the number of items in the hash in not 1" do lambda{@empty_hash.merge_add!({101 => 2, 102 => 3})}.should raise_error(RuntimeError, "Can only pass hash with one item to be added") end it "should create a new Array & wrap new value as an array" do @empty_hash.merge_add!( {101 => 2} ) @empty_hash[101].should eql([2]) end it "should create a new Array & use the array passed as the value" do @empty_hash.merge_add!( {101 => [2]} ) @empty_hash[101].should eql([2]) end it "should migrate existing value to an Array, then add the new value, if existing value is NOT an array" do @hash_with_number.merge_add!( {100 => 2} ) @hash_with_number[100].should eql([1, 2]) end it "should migrate add the new value to existing, if existing value IS an array" do @hash_with_array.merge_add!( {100 => 2} ) @hash_with_array[100].should eql([1, 2]) end end ================================ tks ------=_Part_5835_2746402.1225020018466--