SitePoint Sponsor

User Tag List

Results 1 to 2 of 2

Hybrid View

  1. #1
    SitePoint Zealot
    Join Date
    Nov 2004
    Location
    Yakima WA.
    Posts
    100
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Introduction to Ruby Blocks.

    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

  2. #2
    SitePoint Member
    Join Date
    Oct 2005
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks. It clears up some 'visualization' problems I've had with blocks. I'm new to Ruby though.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •