OK lets take a look at ruby blocks and a few of the most common uses for them. In ruby you usually prefer the .each iterator over a for loop. And actually if you write a for loop in ruby it gets translated to an .each iterator behind the scenes, so for loops are a tad slower than iterators. So lets play with a few arrays and hashes and their .each block iterators:

Code:
array = ['zero', 'one', 'two', 'three', 'four']
array.each {|element| puts element }
# Prints:
zero
one
two
three
four
So we just took each element in the array, one at a time and stuffed it into the element argument to the block. Then the block executed the puts statement. So the block is like an anonomous function. It takes one item from the array at a time as the variable element between the goal posts and then executes the body of the block on that variable.

So lets do the same thing with a hash. You will notice that this .each block takes two arguments, namely the hash key/value pairs:

Code:
hash = {:one => 'foo', :two => 'bar', :three => 'baz'}
hash.each{|key, val| puts "Key: #{key}, Value: #{val}" }
# Prints:
Key: two, Value: bar
Key: three, Value: baz
Key: one, Value: foo

So you can think of blocks like this... The variables between the goal posts are like arguments to a method and the code in the body of the block is executed like it was the body of a method. So thats why they call them anonomous functions, they act like co-routines or methods without a name that you can pass to other methods to customize their behavior.

Now lets write a method that takes a block and see how this yield stuff works:

Code:
def blockhead(num1, num2)
  if block_given?
    yield(num1 + num2) 
  else
    return(num1 + num2)
  end
end

>> puts blockhead(2, 6)
# =>8
>> puts blockhead(2, 6){|sum| sum * 5}
# => 40
Ok lets reason out whats going on with this thing here... When you call blockhead with two numbers and no block, it will just return the sum of the two arguments, nothing special here. But when you give it the same two arguments but also pass a block it starts to get interesting. So if block_given? returns true if you called the method with a block so it executes the next line: yield(num1 + num2) what this does is yeild to the block. First it executes num1+num2 which equals 8. So it passes the integer 8 to your block as sum inbetween the goalposts. then sum gets multiplied by 5 which equals 40. So you can see that by passing a block or anonomous function along with the regular arguments to the blockhead method lets the block customize the behavior of the method by multiplying the sum times 5.

Hopefully that helps clear things up a little bit. Post any questions you might have.

-Ezra