Ben Giddings
10/24/2007 9:14:00 PM
On 04:50 Thu 25 Oct , Thufir wrote:
> "code_words.each do |real, code|
> idea.gsub!( real, code )
> end
> You see the each method? The each method is all over in Ruby. It's
> available for Arrays, Hashes, even Strings. Here, our code_words
> dictionary is kept in a Hash. This each method will hurry through all
> the pairs of the Hash, one dangerous word matched with its code word,
> handing each pair to the gsub! method for the actual replacement."
>
> from page 33 of whys-poignant-guide-to-ruby.pdf
>
>
>
> Is this similar to nested for statements? I don't think so. In the
> first line, why are both "real" and "code" part of the interation?
> >From my understanding of a hash, you can iterate through the keys only
> and then find the corresponding bit of the hash.
>
> Why would this fail:
>
> code_words.each do |real|
> idea.gsub!( real, code )
> end
What's happening in the first version of the code is that "real" and
"code" are being assigned from within the "each" method. At some
point within each there's some code that essentially looks like:
"yield(current_hash_key, current_hash_value)". When that code is run,
ruby assigns the variable (in your scope) real to the value of
"current_hash_key" within the "each" method, and it assigns the
variable "code" to the value of "current_hash_value".
Because "yield" has two arguments, the block you pass each should have
two parameters, which it does. If you used this instead:
code_words.each do |foo|
...
end
Foo would be assigned an array containing both things sent by "yield",
i.e. foo[0] would be the same as real, and foo[1] would be the same as
code.
The key thing here is that not every "each" is the same. Some have a
"yield" that tries to send out one value (like the "each" for arrays),
some pass multiple values (like the "each" for hashes). You need to
know how many variables your "each" wants to assign in a block.
In your example:
code_words.each do |real|
idea.gsub!( real, code )
end
real would get assigned, but "code" wouldn't have been assigned, so
Ruby wouldn't know what "code" was and would complain.
Ben