Reputation: 1121
Is there documentation on the differences of initialization? The docs on Hash didn't have anything that would explain the difference.
foo = [1,2,3,4]
test1 = Hash.new([])
test2 = Hash.new{|h,k| h[k] = []}
foo.each do |i|
test1[i] << i
test2[i] << i
end
puts "test 1: #{test1.size}" #0
puts "test 2: #{test2.size}" #4
Upvotes: 0
Views: 48
Reputation: 21791
There's a difference, in some situation it could be significant
test1 = Hash.new([])
test2 = Hash.new{|h,k| h[k] = []}
test1['foo'] #=> []
test2['foo'] #=> []
test1.keys == test2.keys #=> false
The first construction just returns the default value but doesn't do anything with current hash but second construction initialize the hash with key/value where value is calculated by given block.
Upvotes: 1
Reputation: 168101
There is mentioning in the doc. Read the doc:
new(obj) → new_hash
new {|hash, key| block } → new_hash
[...] If obj is specified, this single object will be used for all default values. If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block’s responsibility to store the value in the hash if required.
h = Hash.new("Go Fish")
h["a"] = 100
h["b"] = 200
h["a"] #=> 100
h["c"] #=> "Go Fish"
# The following alters the single default object
h["c"].upcase! #=> "GO FISH"
h["d"] #=> "GO FISH"
h.keys #=> ["a", "b"]
# While this creates a new default object each time
h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
h["c"] #=> "Go Fish: c"
h["c"].upcase! #=> "GO FISH: C"
h["d"] #=> "Go Fish: d"
h.keys #=> ["c", "d"]
Upvotes: 3
Reputation: 80065
This is a common gotcha. With test1 (the non-block) you are modifying the default object, the thing which you get when the key does not exist in the hash.
foo = [1,2,3,4]
test1 = Hash.new([])
test2 = Hash.new{|h,k| h[k] = []}
foo.each do |i|
test1[i] << i
test2[i] << i
p test1['doesnotexist'] #added line
end
puts "test 1: #{test1.size}" #0
puts "test 2: #{test2.size}" #4
Output:
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
test 1: 0
test 2: 4
Upvotes: 1