Created
January 8, 2015 10:00
-
-
Save DanielVartanov/2ddf13b43c2aed1e7329 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Consider a hash with a default value: | |
hash = Hash.new([]) | |
p hash[:anything] # => [] | |
hash[:my_array] << :value | |
p hash[:my_array] # => [:value] | |
p hash[:anything] # => [:value] o_O ??!?!?!?! | |
=begin | |
Explanation: | |
We pass an object to `Hash.new()`, that object becomes default value of any key of the hash. | |
But it is *the same object*. | |
Example: | |
=end | |
object = Object.new | |
hash = Hash.new(object) | |
p hash[1].object_id # => 19868300 | |
p hash[2].object_id # => 19868300 (same object, not a duplicate) | |
# Smart people would immediately point out that Hash.new accepts lambda which is called to obtain a default value: | |
hash = Hash.new { Object.new } | |
p hash[1].object_id # => 18889740 | |
p hash[2].object_id # => 18875020 | |
# Let's try: | |
hash = Hash.new { [] } | |
hash[:my_array] << :value | |
p hash[:my_array] # => [] o_O ???!?!!! | |
=begin | |
Explanation: | |
Default value will be returned for any hash key which does not yet has a value. | |
But we don't set a value for `:my_array`. If we unfold `hash[:my_array] << :value` we will get: | |
``` | |
array = hash[:my_array] | |
array << :value | |
``` | |
no value has been set for hash[:my_array] | |
What to do then? | |
=end | |
hash = Hash.new { |hash, key| hash[key] = [] } | |
hash[:my_array] << :value | |
p hash[:my_array] # => [:value] | |
p hash[:anything_else] # => [] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment