Can someone explain the following code in Ruby? | Sololearn: Learn to code for FREE!
Novo curso! Todo programador deveria aprender IA generativa!
Experimente uma aula grƔtis
+ 7

Can someone explain the following code in Ruby?

I have this code: h = Hash.new{ 1 2 3 } The following statements all results in printing out 3: puts h [0] puts h [1] puts h [2] puts h [3] > 3 Have tried Google but am not sure what to search for. So you guys are my last hope.

17th May 2018, 8:09 AM
Adam Aksu
Adam Aksu - avatar
8 Respostas
+ 3
Hashes have a thing called aĀ default_proc, which is simply a proc that Ruby runs when you try to access a hash key that doesn't exist. This proc receives both the hash itself and the target key as parameters. You can set a Hash'sĀ default_procĀ at any time. Passing a block parameter toĀ Hash.newĀ simply allows you to initialize a Hash and set itsĀ default_procĀ in one step: h = Hash.new h.default_proc = proc{ |hash, key| hash[key] = 'foo' } # The above is equivalent to: h = Hash.new{ |hash, key| hash[key] = 'foo' } We can also access the default proc for a hash by callingĀ h.default_proc. Knowing this, and knowing that the ampersand (&) allows a proc passed as a normal parameter to be treated as a block parameter, we can now explain how this code works: cool_hash = Hash.new{ |h, k| h[k] = Hash.new(&h.default_proc) } The block passed toĀ Hash.newĀ will be called when we try to access a key that doesn't exist. This block will receive the hash itself asĀ h, and the key we tried to access asĀ k. We respond by settingĀ h[k](that is, the value of the key we're trying to access) to a new hash. Into the constructor of this new hash, we pass the "parent" hash'sĀ default_proc, using an ampersand to force it to be interpreted as a block parameter. This is the equivalent of doing the following, to an infinite depth: cool_hash = Hash.new{ |h, k| h[k] = Hash.new{ |h, k| h[k] = Hash.new{ ... } } } The end result is that the key we tried to access was initialized to a new Hash, which itself will initialize any "not found" keys to a new Hash, which itself will have the same behavior, etc.Ā It's hashes all the way down. Source: stackoverflow.com/questions/20158213/ruby-hash-creating-a-default-value-for-non-existing-elements
17th May 2018, 10:45 AM
Nikita Semenov
Nikita Semenov - avatar
+ 2
Should this code when no key is defined result in the default value is set to 3, that is the last value?
17th May 2018, 8:36 AM
Adam Aksu
Adam Aksu - avatar
+ 2
Hashes have aĀ default valueĀ that is returned when accessing keys that do not exist in the hash. If no default is setĀ nilĀ is used. You can set the default value by sending it as an argument toĀ ::new: grades = Hash.new(0)
17th May 2018, 9:08 AM
Nikita Semenov
Nikita Semenov - avatar
+ 2
[user id="3613244"]Nikita Semenov www.taskker.club[/user] I think the hash's default value is set to 3 somehow. But when using statement: p h.default the result is 'nil'. However, if trying to print a non-existing value, such as 'key1' it prints 3. p h['key1' #prints 3 So it behaves as default value is set to 3
17th May 2018, 10:23 AM
Adam Aksu
Adam Aksu - avatar
+ 2
"The truth is out there" (c)
17th May 2018, 10:52 AM
Nikita Semenov
Nikita Semenov - avatar
+ 2
Thanks [user id="3613244"]Nikita Semenov www.taskker.club[/user] . I just tried this def 1 2 3 end p h # prints 3 So the block in the hash in my question is returning 3 the last thing it does and therefore default value is set to 3? Don't understand though why p h.default doesn't print 3.. But that is maybe explained in the link you provided.. will read that.
17th May 2018, 10:58 AM
Adam Aksu
Adam Aksu - avatar
+ 2
h1 = Hash.new(7) h1.default #=> 7 h1.default_proc #=> nil h1[123] #=> 7 h2 = Hash.new{7} h2.default #=> nil h2.default_proc.call #=> 7 h2[123] #=> 7 Hope this will help you to understand
17th May 2018, 11:14 AM
Nikita Semenov
Nikita Semenov - avatar
+ 2
I guess when you call h[123] ruby return h.default. If result is nil, then it search for h.default_proc and return h.default_proc.call
17th May 2018, 11:19 AM
Nikita Semenov
Nikita Semenov - avatar