Iterating Over Hashes; What's the Point of This 'b' Here Anyway?


#1



Here's my question: In the matz.each block below, why is it necessary to include that "b" in |a,b| ? I'd chosen not to use "key" and "value" as my placeholders, to confirm for myself that those could just as easily have been any other words or letters from the Ruby interpreter's perspective.

But then why do you need to put two placeholders when ultimately you're only using one? Why is the second approach I've included below, with just an "|a|" placeholder, not correct? Does simply including two placeholders indicate to the interpreter somehow that you are talking about key-value pairs where the second placeholder is the value? Can anyone provide some info on what's really going on with that |a,b| part and what, in contrast, the interpreter would be doing with just |a| instead? I can make the code work, but I don't have a satisfying understanding of why those two scenarios are different.


#CORRECT SOLUTION
matz = { "First name" => "Yukihiro",
  "Last name" => "Matsumoto",
  "Age" => 47,
  "Nationality" => "Japanese",
  "Nickname" => "Matz"
}

matz.each do |a,b|
    puts matz[a]
end

#INCORRECT SOLUTION
matz = { "First name" => "Yukihiro",
  "Last name" => "Matsumoto",
  "Age" => 47,
  "Nationality" => "Japanese",
  "Nickname" => "Matz"
}

matz.each do |a|
    puts matz[a]
end


#2

You're giving matz.each (matz is a Hash, so it's Hash#each https://docs.ruby-lang.org/en/2.0.0/Hash.html#method-i-each) a block, and as each runs it'll call your block once for every entry. It'll call it with two arguments because that's just how it behaves. There are versions for just keys and just values as well.
You can still give it a block that only accepts one argument, question is in what way you consider that wrong


#3

Thanks for the response here as well. It seems likely I'm either misunderstanding or poorly understanding some of your answer.

"It'll call it with two arguments because that's just how it behaves. There are versions for just keys and just values as well."

My understanding of "it'll call it with two arguments because that's just how it behaves" is that hashes have this fundamental property: When you call blocks on them, you need to give them two block parameters, corresponding to a key and a value, regardless of whether you're interested in both parameters, because this is just how blocks for hashes are written in a meaningful way. Is that what is meant?

As for what you wrote here: "You can still give it a block that only accepts one argument, question is in what way you consider that wrong"

I'm considering the second approach above to be wrong in the context of the lesson, since it fails to puts out the values of the hash. It actually makes sense to me that it doesn't work, because it seems like, by giving only one parameter, there's no way to distinguish whether you're after the key or the value. But, the inclusion of that "b" as a block parameter in "do | a, b| " above just struck me as suspiciously arbitrary given that we ultimately don't use the "b" in the rest of the block, so I wanted to understand better what was really going on. Are there in fact ways that you could call a block on a hash, using only one parameter, and use it to return the values, or the keys, depending on which we wanted?


#4

No there's no such property aside from how the each method for Hash behaves.

It gives you both. As an array. In order for your code to "work" you'd have to treat it as such. If you have an array and treat it as if it was one of the values in that array.. it shouldn't work, and you wouldn't be able to point at the documentation and motivate why it would.

It is arbitrary, yes. Somebody had to make a decision about how those methods should behave. To make use of the methods, you'll first need to look up how it's meant to behave.

Somebody wrote some piece of code that is useful, they gave it some particular input and output specifications, and to use their code you gotta know what those are.

That method behaves slightly differently based on how you use it, there are also others that do similar things, those too are listed on the same page in that documentation for the Hash class.

If you read the description in that documentation, that says what the method does (which is to provide key-value pairs in a couple of different ways based on how it's called). If you expect any other behaviour, such as only the keys, then you would be looking for a different method (or ignore the values, since the keys can indeed be obtained through this method)


#5

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.