The below is all him, from Chapter 3 of his poignant guide to ruby. It may help you to grok blocks, if you’ve got a ‘huh?!’ going like I did when I first learned about them. And in any case, you should know about _why, because everyone does, and Ruby people are always talking about chunky bacon and cartoon foxes, and _why is why.
Blocks
Any code surrounded by curly braces is a block.
2.times { print “Yes, I’ve used chunky bacon in my examples, but never again!“ }is an example.
With blocks, you can group a set of instructions together so that they can be passed around your program. The curly braces give the appearance of crab pincers that have snatched the code and are holding it together. When you see these two pincers, remember that the code inside has been pressed into a single unit.
It’s like one of those little Hello Kitty boxes they sell at the mall that’s stuffed with tiny pencils and microscopic paper, all crammed into a glittery transparent case that can be concealed in your palm for covert stationary operations. Except that blocks don’t require so much squinting.
The curly braces can also be traded for the words do and end, which is nice if your block is longer than one line.
loop do
print “Much better.“
print “Ah. More space!“
print “My back was killin’ me in those crab pincers.“
end
Block arguments
Block arguments are a set of variables surrounded by pipe characters and separated by commas.
|x|,|x,y|, and|up, down, all_around|are examples.
Block arguments are used at the beginning of a block.
{ |x,y| x + y }
In the above example, |x,y| are the arguments. After the arguments, we have a bit of code. The expression x + y adds the two arguments together.
I like to think of the pipe characters as representing a tunnel. They give the appearance of a chute that the variables are sliding down. (An x goes down spread eagle, while the y neatly crosses her legs.) This chute acts as a passageway between blocks and the world around them.
Variables are passed through this chute (or tunnel) into the block.
September 28th, 2007 at 1:23 pm
Just don’t call the x and y in |x, y| arguments. They’re parameters.
September 28th, 2007 at 6:36 pm
I prefer to call them altercations.
October 1st, 2007 at 2:11 pm
I heartily recommend the soundtrack:
http://www.poignantguide.net/sdtrk/
October 1st, 2007 at 2:53 pm
From Amy’s list of blogs, I found: http://www.oreillynet.com/ruby/blog/2007/06/on_the_horizon_ten_things_i_li.html
which confirms the unexpected behavior I had been seeing:
7. Block arguments are always local
a = 1
10.times{|a| } # !> shadowing outer local variable - a
a # => 1
Compared to the nasty behaviour on 1.8:
a = 1
10.times { |a| }
a # => 9
October 1st, 2007 at 5:06 pm
It will be exciting to see how much code the 1.9 behavior breaks! Arguably, the 1.8 behavior is not unreasonable.
October 2nd, 2007 at 8:23 am
I think the 1.8 behavior makes lots of sense, but I’ve also always thought that the parameters to a block should not be named the same as a variable outside of the block, as in a.inject(){ |a, b| do stuff}, for just that reason that it forces people to remember the scope stuff. I think it’s important to understand the scoping rules, but do you really want to rely on other developers reading/modifying your code to remember and understand them correctly?
October 2nd, 2007 at 11:11 am
I never grokked http://poignantguide.net/ruby/index.html, but Erik’s right, if you read it while playing the soundtrack, it all starts to make sense.