If you read the beginning of the previous section, you might have been
discouraged. ``Ruby has pretty primitive built-in looping
constructs,'' it said. Don't despair, gentle reader, for there's good
news. Ruby doesn't need any sophisticated built-in loops, because all
the fun stuff is implemented using Ruby iterators.
For example, Ruby doesn't have a ``for'' loop---at least not the kind
you'd find in C, C++, and Java. Instead, Ruby uses methods defined in
various built-in classes to provide equivalent, but less error-prone,
functionality.
Let's look at some examples.
3.times do
print "Ho! "
end
|
produces:
It's easy to avoid fencepost and off-by-1 errors; this loop will
execute three times, period. In addition to
times
, integers
can loop over specific ranges by calling
downto
,
upto
, and
step
. For instance, a traditional ``for''
loop that runs from 0 to 9 (something like
i=0; i < 10; i++
)
is written as follows.
0.upto(9) do |x|
print x, " "
end
|
produces:
A loop from 0 to 12 by 3 can be written as follows.
0.step(12, 3) {|x| print x, " " }
|
produces:
Similarly, iterating over arrays and other containers is made easy
using their
each
method.
[ 1, 1, 2, 3, 5 ].each {|val| print val, " " }
|
produces:
And once a class supports
each
, the additional methods in the
Enumerable
module (documented beginning on page 403
and summarized on pages 102--103)
become available. For example, the
File
class provides an
each
method, which returns each line of a file in turn. Using
the
grep
method in
Enumerable
, we could iterate over only
those lines that meet a certain condition.
File.open("ordinal").grep /d$/ do |line|
print line
end
|
produces:
Last, and probably least, is the most basic loop of all. Ruby provides
a built-in iterator called
loop
.
The
loop
iterator calls the associated block forever (or at
least until you break out of the loop, but you'll have to read ahead
to find out how to do that).