The Pragmatic Studio

Block Basics

Exercises

Overview

Blocks in Ruby are simply chunks of code between braces (single-line blocks) or between do and end (multi-line blocks). You can't execute a block of code directly. Instead, you must associate a block with a call to a method. When the method runs, it turns around and executes the code in the block. Depending on the method, it can also pass parameters to the associated block.

Now that you've seen blocks in action in the video, it's your turn!

1. Play With Blocks

Ruby has a number of built-in methods that take blocks. So let's begin with some basic blocks to warm up the fingers...

  1. If you haven't already done so, create a new Ruby program file called block_basics.rb where you can play around with blocks.

  2. Start by using the times method with a block to print the following workout steps, 5 times:

    situp
    pushup
    chinup
  3. That's a good start, but now suppose you want to prefix each step with the repetition number, like so:

    0 situp
    0 pushup
    0 chinup
    
    1 situp
    1 pushup
    1 chinup
    
    ... and so on
    
    4 situp
    4 pushup
    4 chinup

    To do that, recall that the times method will pass the current iteration to the block. You can capture that number in a block parameter. Remember that block parameters sit between vertical bars at the start of the block. Here's the general form for a block that takes one parameter:

    object.method do |parameter|
      # block code
    end
    
    # or for a single-line block:
    
    object.method { |parameter| ... }
    
  4. You know your fitness instructor is a bit odd when she starts counting with zero. Unfortunately, the times method counts like a programmer. Change the code to use the upto method, which counts more like a fitness pro, to count the repetitions from 1 through 5. Here's the output you're aiming for:

    1 situp
    1 pushup
    1 chinup
    
    2 situp
    2 pushup
    2 chinup
    
    ... and so on
    
    5 situp
    5 pushup
    5 chinup

Warmed up? Perfect! Here's the take-away: Although you attach a block to a method, the block is not a method parameter. The method and its parameters are totally separate from the code block. We'll see how methods actually call a block a bit later.

2. Create Frequent Flyers

Let's apply what we've learned about blocks toward something a bit more realistic. Suppose you're developing a frequent flyer program. To keep it simple for now, each frequent flyer has a name, email, and number of miles flown, which is represented in the following Flyer class:

class Flyer
  attr_reader :name, :email, :miles_flown

  def initialize(name, email, miles_flown)
    @name = name
    @email = email
    @miles_flown = miles_flown
  end

  def to_s
    "#{name} (#{email}): #{miles_flown}"
  end
end

Notice that the class defines a convenient to_s method that returns a formatted string representing a specific flyer.

  1. Go ahead and copy the code above into a new Ruby program file called flyer.rb. We'll build off this class over the next several exercises.

  2. Then create an array of five flyers, each with unique names, emails, and number of miles flown. Rather than creating them one by one, use your friend the upto method with an associated block to create and add each flyer to the array.

    Once you've filled up the array of flyers, print the array using puts. Passing an array to puts will print each element in the array using the string returned by the object's to_s method. Your goal is the following output:

    Flyer 1 (flyer1@example.com): 1000
    Flyer 2 (flyer2@example.com): 2000
    Flyer 3 (flyer3@example.com): 3000
    Flyer 4 (flyer4@example.com): 4000
    Flyer 5 (flyer5@example.com): 5000
  3. Once you get that working, feel free to experiment! For example, try changing the name of the block parameter.

Solution

All the exercise solutions, as well as the example code we write in the videos, is available for download in the code bundle file (right-click to save). No peeking until you try! When you unzip the file, you'll end up with a directory called pragstudio-ruby-blocks-code. Inside that directory, you'll find two sub-directories: exercise-solutions and video-code. And inside each of those directories you'll find code organized into sub-directories matching the names of the course modules.

The full solution for this exercise is in the block-basics directory of the code bundle.

Pop Quiz

Take a minute to review the main concepts you've learned in this section, and let them sink in before moving on.

  1. By convention, multi-line blocks to start with ________ and end with ________.

  2. By convention, single-line blocks to start with ________ and end with ________.

  3. Block parameters are always placed within ________.

  4. Convert the following code from a multi-line block to a single-line block.

    1.upto(10) do |count|
      puts "#{count} alligator"
    end
    
  5. In the example below, the value of the method parameter is ________.

    1.upto(5) do |count|
      puts "#{count} situps"
      puts "#{count} pushups"
      puts "#{count} chinups"
    end
    
  6. In the example above, the block parameter is ________ and it is a ________ variable.

Bonus Round

Suppose you wanted to continue doing five repetitions of each exercise, but counting by 2, starting with 1 and ending with 9. (It's a new fad in exercise, trust us!) In that new regimen, here's the output you're looking for:

1 situp
1 pushup
1 chinup

3 situp
3 pushup
3 chinup

... and so on

9 situp
9 pushup
9 chinup

To do that, we need to introduce you to a new method. Similar to the upto method, Ruby also has a step method. It takes two parameters: the upper limit and the step interval.

Give it an honest try before looking at the answer!

Wrap Up

So now that you've been around the ol' block (sorry, that was lame), you now know how to:

  • call methods that take blocks (such as times and upto)
  • write single and multi-line blocks
  • write blocks that take parameters

Here's a visual overview of what we learned in this section (click to enlarge):

For quick and handy reference, download all the cheat-sheet summaries in a single summary PDF.

Everything from here forward builds on this basic foundation! Next up we'll use blocks with another iterator method: each. It's super powerful and you'll see (and use) it extensively in Ruby and Rails.

All course material, including videos and source code, is copyrighted and licensed for individual use only. You may make copies for your own personal use (e.g. on your laptop, on your iPad, on your backup drive). However, you may not transfer ownership or share the material with other people. We make no guarantees that the source code is fit for any purpose. Course material may not be used to create training material, courses, books, and the like. Please support us by encouraging others to purchase their own copies. Thank you!

Copyright © 2005–2024, The Pragmatic Studio. All Rights Reserved.