Learning Ruby [iterator control structures]

Iterators are methods that have the ability to iterate through a collection, such as an array or hash table. During each iteration, these methods yield one or more values to a code block that is defined when the method is called. This code block is used in different ways depending on the type of iterator method that has been called.

Before delving deeper into iterator methods, let’s take a look at the concept of yielding. The yield method enables a method to yield to a code blocks that is defined along with a method call. This means that where ever you add the keyword yield in your method, Ruby will look for a code block to insert here when the method is called. As a consequence, methods that include a call to yield require that a code block be defined when they are called.

The code blocks functions though they were running inside the method that yielded to them. Data can be shared between the method and code block. To send data to the code block, arguments can be provided to the yield method just as with any other method. These arguments are available in the code block using the syntax | var_1, var_2 |. The examples below show this in action.

def yielding_method
    puts pre-yield
    yield(message from yielding method)
    puts post-yield
end

yielding_method {|i| puts yield code block #{i}” }

view raw gistfile1.rb This Gist brought to you by GitHub.

The yield method can also return a value from the code block. It returns the value from the last expression in the code block to which it yielded – notice that this is the same rule that applies to method returns).

In the example below the value returned by the yielded method is assigned to a variable called return_vals. The actual value returned by the code block is string. If the yielding_method was an iterator method we use an array to capture the data returned from each iteration.

def yielding_method
    puts pre-yield
    return_vals = yield(message from yielding method)
    puts post-yield #{return_val}”
end

yielding_method do |i|
    puts yield code block #{i}”
    str = message from code block back to method
end

view raw gistfile1.rb This Gist brought to you by GitHub.

Now let’s take a look at the three most commonly iterator methods. Times is a popular iterator that can be called on any integer object, and it will loop from 0 until it reaches the integer number on which it was called. This method is a nice and concise way to create a simple loop. When it is done iterating, the times method returns the original integer number.

4.times {|cur_num| code block to run}
view raw gistfile1.txt This Gist brought to you by GitHub.

The each method can be used with collection classes, such as arrays. It loops through each element in the given collection class, and let’s you define a block of code that receives the current element from the collection via a parameter. When it is done iterating, each returns the original array.

my_array = [1, 2, 3, 4]
my_array.each {|cur_element| code block to run}

view raw gistfile1.rb This Gist brought to you by GitHub.

The map iterator is similar to each, in that it is designed to work with collection classes. However, map returns an array, of the same value as the original collection, containing the return values from the code block. When you use map you have to make sure that the last expression in your code block will return the value that you want to capture in the array that is returned.

my_array = [1, 2, 3, 4]
new_array = my_array.map {|cur_element| cur_element += 2}

view raw gistfile1.rb This Gist brought to you by GitHub.

One Response to “Learning Ruby [iterator control structures]”

Leave a Reply