Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hash default value not being used [duplicate]

Today I tried the following snippets of code and I don't understand why I get different results between them. As far as I can understand they are the same.

One uses the default value off Hash and the other snippet creates an empty array for the key before it'll be accessed.

Anyone who understands what's going on? :)

# Hash default if the key doesn't have a value set is an empty Array
a = Hash.new([])
a[:key] << 2 # => [2]
p a # => {} nil
p a[:key] # => [2]
p a.keys # => []
p a.values # => []

# Explicitly add an array for all nodes before creating
b = Hash.new
b[:key] ||= []
b[:key] << 2 # => [2]
p b # => {:key=>[2]}
p b.keys # => [:key]

Ruby version 1.8.7

like image 213
gaqzi Avatar asked Nov 23 '25 14:11

gaqzi


2 Answers

Maybe this will help:

a = Hash.new { |hash, key| hash[key] = [] }
a[:key] << 2 # => [2]
a[:key]      # => [2]
p a          # => {:key=>[2]}
like image 91
maček Avatar answered Nov 26 '25 09:11

maček


When you did a[:key] << 2, you slipped that empty array default value out and added 2 to it (modifying the actual array, not the reference) without letting the hash object a know that you had changed anything. You modified the object that a was using as a default, so you will see this as well:

p a[:wat] #=> [2]
p a[:anything] #=> [2]

In the second example, you made a new array, and use b[:key]= which tells b that it has a value under that key.

Try this if you want the best of both worlds:

c = Hash.new([])
c[:key] += [2]

This will access c[:key] and make a new array with + and reassign it.

like image 30
mckeed Avatar answered Nov 26 '25 09:11

mckeed



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!