Printing a Value from a Hash


I'll use "Hashes and Symbols", section 2 as an example for this question.

I understand that in order to print out the value for the matz hash one must type

matz.each {|key,value| puts key, matz[key]}

It's the "matz[key]" that I'm hung up on. Why must we type "key" when it's the value we're looking to put out? Wouldn't matz[value] make more sense? I understand that we can also type:

matz.each {|key, value| puts "#{value}"}

and this makes much more sense to me. I can get through the question but I want to understand why it works the way it does. Am I not grasping something intuitive? Thank you for your help!


As close as I can tell, the second variable in the block parameter is a value placeholder, or alias for matz[key]. When it is not present, nothing is outputted:

matz.each { |key| puts matz[key] }         # no output

matz.each { |key, value| puts matz[key] }  # shows output

matz.each { |key, value| puts value }      # shows output

In the above, puts is printing string values. When the value is not a string, I believe puts converts it to string, if it can. That's where value interpolation comes in. It can take any value (or expression) and represent it in string form.

matz.each { |key, value| puts "#{value}" }  # same output

I'm sure this is only a scratch on the surface of a good answer, but it should start one in the right direction.


Just to zero in on this part of the question, this is the kind of notation you use to find a value in a hash when you don't necessarily know what the value is. matz[key] finds the matz hash, then finds the provided key, and returns the value associated with that key.

You can try this outside of a loop to better see what's happening:

my_hash = { "key1" => "val1",  "key2" => "val2", "key3" => "val3" }

should return the value of key2, which is val2.

It seems more intuitive that, since we already have the current value of the current key available through the method parameter 'value', we should just use 'value' - but since this hash[key] notation expects you to give it a key, if you give it a value it's not going to work.

In this case, since we already have the value, just using puts value seems like the simplest way to write it. I don't think you need string interpolation either.


Thank you, I finally understand what's going on here and it's been bugging me for ages. Much appreciated.