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