Block return values

Remember that we said a block returns a value just like methods do? So far, in our two examples above, we did not do anything with the return values of the block.

Here’s an example that does that:

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

This will take the array of numbers, and transform it into another array.

It does this by calling the method collect on the original array, which calls the given block for each of the elements, and collects each of the return values returned by the block. The resulting array is then returned by the method collect, and printed to the screen.

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

Note that the method collect has an alias, which is map. These are exactly the same methods. Many programmers prefer map over collect because it is shorter, and also more commonly used in other languages. However, in our study groups we use collect more often, because it simply expresses more clearly what the method does.

Use the method collect to transform an array into another array.

Here’s another example that uses the return value of the block, can you guess what it does?

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

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

Let’s walk through this step by step, under the microscope:

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

Use the method select to select a new array with values that match a criteria defined by the block.

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

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

Again, detect will pass each of the elements of the array to the block, one by one, and check the return value of the block. However, as soon as the block returns something truthy (something that is “equivalent to true”), the method detect will return the current object itself. Therefore, this will print out 2: the first number in the array that is even.