I think it's kind of funny no one's pointed this out yet. The anatomy
of a block:
{ |argument, list| code.to(execute) }
A block is built a little like a method, though it has no name and
only exists while it is executing (as others has said). The bits
between pipes are like the argument list in a method and the bits
after that are to be run. Maybe this will help:
def some_method(argument, list)
code.to(execute)
end
See the similarity? Now, the reason the semantics change based on what
method the block is attached to is because each method (not THE each
method) passes a different thing (or set of things) as arguments.
Integer.times passes numbers (as illustrated above). Other methods
pass nothing at all. It's almost like... passing a little method to
another method as an argument, knowing that the method you're calling
will execute that code in a certain way (just like you know it'll do
other stuff to normal arguments you pass in) and give you back
something helpful.
I hope that's clear. Sometimes I get rambly and don't actually explain anything.
Ben