Ruby for Newbies: Iterators and Blocks


Ruby is a one of the most popular languages used on the web. We've started a new screencast series here on Nettuts+ that will introduce you to Ruby, as well as the great frameworks and tools that go along with Ruby development. In this chapter, we’ll talk about in blocks and iterators.

Catch Up

View Screencast

Click the HD button for a clearer picture.

Subscribe to our YouTube page to watch all of the video tutorials!


In the last lesson, we talked about loops. You actually won’t use loops too often in Ruby, because of a feature called blocks (and—as a result of blocks—iterators). To refresh your memory, look at the two following method calls (you can try this in IRB):

name = "Joe"

name.reverse  # => "eoJ"

name.concat(" the Plumber") # => "Joe the Plumber"

As you know, the parentheses after the method call are usually optional. We’ll learn today when they are required.

So, here are the parts of a method call:

  • The object receiving the method; name above.
  • The dot.
  • The method name; reverse or concat above.
  • The arguments; " the Plumber" in the second example above.
  • The code block; stay tuned!

The first three parts are required, obviously. The arguments and the code block are optional. What is this code block? Look at this example, and then we’ll discuss it:

sites = ["net", "psd", "mobile"]! do |site|
    site += ""

sites # => ["", "", ""]

In this case, the array sites is the receiver; the method is map!. Next we have the block. If the block is on multiple lines, you can use the keywords do and end to delimit it. If you’re putting it on a single line, you can use curly braces (these work for multi-line blocks, too).

After the opening of the block, we have the block parameters, within pipes ( | ). What this is really depends on the method you’re executing. The most common use of blocks are in iterator methods, so the block parameter will be the current item in the looping. If this sounds rather abstract, we’ll do a few examples.


We’ll start by looking at the iterators of arrays, because they’re the most commonly looped over thing.

Instead of using a for loop, you’ll probably use each:

sites = ["net", "psd", "mobile"]

sites.each { |site|
    puts "#{site}"

This is just like doing a for loop; one by one, each item in sites will be assigned to the block parameter site; then, the code inside the block will be executed.

In case you’re curious, the each method returns the original array.

Sometimes, you’ll want to return a value from the block. That’s not hard to do, if you use the right method.

# assume sites above

sites = do |s|

The map method collects whatever values are returned from each iteration of the block. Then, an array of those values is returned from the method. In this case, we’re reassigning the sites variable to the new array.

There’s a better way to do this, though. Several Ruby methods have duplicates with the exclamation mark (or bang); this means they are destructive: they replace the value they are working on. So the above could be done this way:! { |site_prefix| "#{site_prefix}" }

Now, sites will be the array of values returned from the block.

More than just arrays have iterator methods, though. Numbers have a pretty cool times method:

5.times do |i|
    puts "Loop number #{i}"
# Loop number 0
# Loop number 1
# Loop number 2
# Loop number 3
# Loop number 4

As you continue coding Ruby, you’ll find a lot of useful methods that use blocks. Now, let’s see how to create our own blocks.

Building Blocks

Now that you’re familiar with using blocks, let’s see how to write methods that take advantage of them. Here are two other block tidbits that you haven’t learned yet:

  • Block parameters are not required; you can write a block that doesn’t use them.
  • Blocks themselves can be optional. You can write a function that works with or without blocks.

Here’s what happens you call a method that takes a block. Behind the scenes, Ruby is executing some method code, then, yielding to the block code. After that, control is returned to the method. Let’s check it out.

Since most of the simple iterator functions are built into Ruby, we’ll “rewrite” one of those. Let’s do the each method on arrays:

class Array
    def each2 
        i = 0;
        while self[i]
            yield self[i]
            i += 1

As you can see, this is just a normal method. Remember that within an instance method, the self keyword refers to the instance of the class, in this case, Array. Inside the method, we’re using a while loop to loop over the items in the array. Then, inside the loop, we use the yield keyword. We’re passing it self[i]; that will end up being the block parameter. After that, we increment i for the loop and continue.

If we wanted this method to return the array of values that the block returned, we could just capture the returned value of yield and return that, instead of self, we return that array.

class Array
    def each2_returning_new_values
        i = 0;
        new_vals = [];
        while self[i]
            new_vals[i] = yield self[i]
            i += 1

Methods, revisited

Let’s finish up by talking about methods. We know that using parentheses is optional … most of the time. Here’s when you need to use the parenthesis when method calling.

Sometimes, you’ll have both method parameters and a block.

obj.some_method "param" { |x|
    #block code here

What I’ve just done won’t work; we need to use parentheses in this case, because otherwise the block is associated with the last parameter. This is only the case if you use the curly braces to delimit the block; if you use do - end, the parentheses aren’t required.

The other time parenthesis are required is when you’re passing a literal hash (not a variable that points to a hash) as the first parameter of the method. Ruby will think it’s a block, because of the curly brace

arr.push { :name => "Andrew" } # Fails!
arr.push({ :name => "Andrew" }) # Passes
Related Posts
  • Computer Skills
    App Training
    Writing Destinations for DropzoneDropzone400
    Dropzone is not just another FTP upload client, but a great utilities platform for processing files and text. Dropzone is a collection of destinations that can have two types of actions: drag and drop action and/or a click action. There are a lot of pre-programmed destinations to use, but you can also write your own destinations in Ruby!Read More…
  • Computer Skills
    How to Check and Enable TRIM on a Mac SSDTrim preview retina
    You probably know that solid state drives (SSD) differ from Hard Disk Drives (HDD) in how they store information, and you may have heard that something called TRIM can maintain their performance. In this tutorial, I’ll not only show you how you can enable TRIM support for your SSDs, but also understand what the term means and how it fits into the functionality of solid state storage.Read More…
  • Computer Skills
    OS X
    Finding Hardware Faults: Exploring AHT & Apple DiagnosticsAht preview retina
    Alongside the tools provided for identifying software issues with your Mac, Apple also makes sure that you can examine your hardware for possible faults. These hardware diagnostic tools have evolved over the years, so in this tutorial I will cover the two incarnations that exist: the venerable Apple Hardware Test (AHT), and the newer Apple Diagnostics tool that replaced it. In this tutorial I'll show you how you can use these helpful utilities to keep an eye on the components that make your Mac tick.Read More…
  • Code
    iOS SDK
    Objective-C Succinctly: Blocks0e5ds8 preview image@2x
    Blocks are actually an extension to the C programming language, but they are heavily utilized by Apple's Objective-C frameworks. They are similar to C#'s lambdas in that they let you define a block of statements inline and pass it around to other functions as if it were an object.Read More…
  • Code
    Ruby on Rails Study Guide: Blocks, Procs, and LambdasRails history preview image
    Ruby is a language with a set of powerful features - the most powerful arguably being Blocks, Procs, and Lambdas. In short, these features allow you to pass code to a method and execute that code at a later time. Despite regularly using these features, many developers don't fully understand the subtle differences between them.Read More…
  • Code
    JavaScript & AJAX
    Better CoffeeScript Testing With MochaMocha coffeescript
    Recently, I’ve been doing a considerable amount of CoffeeScript work. One problem I ran into early-on was testing: I didn’t want to manually convert my CoffeeScript to JavaScript before I could test it. Instead, I wanted to test from CoffeeScript directly. How’d I end up doing it? Read on to find out!Read More…