Block Return Values

Remember when we learned that a block returns a value just like methods do? So far, in our two previous examples, we didn’t do anything with the block’s return values.

An example using collect

Here’s an example that does that:

Press + to interact
p [1, 2, 3, 4, 5].collect { |number| number + 1 }

This takes the array of numbers and transforms it into another array.

Explanation

  • It does this by calling the collect method on the original array, which executes the given block for each element and collects each array return value returned by the block. The resulting array is then returned by the collect method and printed to the screen.

  • In other words, the collect method uses the block as a transformer. It takes each element of the array, passes it to the block to transform it to something else, and then keeps all transformed values in a new array that the collect method eventually returns.

Note that the collect method has an alias, which is map. These are exactly the same methods. Many programmers prefer map over collect because it’s shorter and more commonly used in other languages. That said, collect is used here because it simply expresses what the method does more clearly.

Remember: The collect and map methods can be used to transform an array into another array.

An example using select

Here’s another example that uses the return value of the block:

Press + to interact
p [1, 2, 3, 4, 5].select { |number| number.odd? }

In this case, the select method uses the block as a filter, or criterion, to select values out of the array and then return a new array with the selected values.

A step-by-step explanation

  1. We create an array, [1, 2, 3, 4, 5].

  2. We then call the select method on it and pass our block.

  3. Now, the select method executes our block for each number.

  4. It first executes the block, passing the number 1 as an argument.

  5. We’re now inside the block, and a local number variable is assigned to the object that was passed as an argument, which is the number 1.

  6. We call the odd? method on this number in our block and because 1 is odd, it returns true.

  7. Because this is the only, and therefore last, statement in the body of our block, it returns true to the select method. The select method therefore keeps (selects) the number 1.

  8. It then executes the block again, this time passing the number 2. Because this isn’t an odd number, the odd? method, and therefore our block, returns false back to the select method. It then discards this element.

  9. It keeps doing this for each remaining element in the array, and it eventually has the [1, 3, 5] array. The block serves as filtering criteria.

  10. The select method then returns this array, and Ruby passes it to the p method, which prints the array out to the screen.

Therefore, the code above prints out [1, 3, 5].

Remember: The select method can be used to select a new array with values that match block-defined criteria.

An example using detect

Here’s another example of a method that uses the block as a criterion:

Press + to interact
p [1, 2, 3, 4, 5].detect { |number| number.even? }

Again, detect passes each element of the array to the block, one by one, and checks its return value. However, as soon as the block returns something true, the detect method returns the current object itself. Therefore, this prints out 2, the first even number in the array.