`Next` and `Break` in Ruby
Passing arguments to common iteration escape methods for better control in enumerables.
Ruby provides two means of escaping from an enumerable: next
will enter the next iteration without further evaluation, and break
will exit from the enumerable entirely.
Let’s take a quick look at both with some simple examples.
Standard implementation (without arguments)
# Example of `next`a = [1, 2, 3]a.each do |num|
next if num < 2
puts num
end# console output
2
3
=> [1, 2, 3]
In the above example we see that 1
is not printed to the console, because the call to next
triggers on the first iteration (1 is less than 2), skipping the puts
statement. The conditional is not met in the following two iterations and the puts
statement outputs num
to the console, as expected, followed by a return of a
.
# Example of `break`a = [1, 2, 3]a.each do |num|
break if num < 2
puts num
end# console output
=> nil
With break
something entirely different has happened. Here, on the first iteration, 1 again is evaluated as being less than 2, and so our call to break
is executed, leaving the enumerable entirely. In this case, we see that future iterations do not take place and nil
is returned.
While this escape is desirable, what if we needed to return something other than nil
? Fortunately, both break
and next
accept an argument to manually set a return value.
Passing arguments
First, let’s look at how it works with break
:
a = [1, 2, 3]a.each do |num|
break num if num < 2
puts num
end# console output
=> 1
Here we’ve passed num
as the argument to break
(remember that parentheses are optional in Ruby, so break num
and break(num)
are evaluated identically) and manually specified the return value. If you should ever need to return something other than nil
when break
is triggered, this can be exceptionally useful.
Since an argument to next
only influences the return value for a particular iteration (rather than the entire loop, as break
does), we’ll move to a slightly different example.
a = [1, 2, 3]a.map do |num|
next 'even' if num.even?
num
end# console output
=> [1, "even", 3]
Truly, passing an argument to next
is not much more than syntactic sugar, as we could re-write the above with an if/else
:
a = [1, 2, 3]a.map do |num|
if num.even?
'even'
else
num
end
end# console output
=> [1, "even", 3]
Summary
Although not always necessary, it is possible to pass an argument to next
and break
in Ruby, setting the return for a particular iteration or an entire loop, respectively.