- Write basic loops with the
while
construct - Use the
#times
method to run a block of code a specified number of times
In this lesson, we'll show how to use control flow to run the same line(s) of code multiple times in a loop. Make sure to follow along by running IRB and experimenting with the example code.
In JavaScript, there are a few common approaches for control flow that will
allow us to run the same lines of code over and over again. The most basic tool
is the while
loop, which works like this in JavaScript:
let i = 0;
while (i < 5) {
console.log("Looping!");
i++;
}
Ruby has a while
construct too, which works much the same way:
i = 0
while i < 5
puts "Looping!"
i += 1
end
Ruby also has an until
loop, which acts like the opposite of a while loop, and
will run a block of code until some condition is true:
counter = 0
until counter == 10
puts "Counting!"
counter += 1
end
JavaScript has a for
loop, which is commonly used to run some condition a set
number of times:
for (let i = 0; i < 10; i++) {
console.log(`Looping!`);
console.log(`i is: ${i}`);
}
While Ruby does also have a for
loop, you will see them used less often by
Rubyists, since Ruby has a few other more expressive ways to run code in a loop.
One such approach is to use the #times
loop:
10.times do |i|
puts "Looping!"
puts "i is: #{i}"
end
The syntax here is quite different from JavaScript, so let's break it down.
#times
is a method in the Integer class that can be called on a
number. It takes a block of code as an argument, starting with do
and ending
with end
, and will run the code inside that block in a loop. You can
optionally provide a block parameter, which in the example above, is
represented by the i
variable within the pipes: |i|
.
Between the do
and the end
, you write whatever code you want to run in the
loop.
Each time Ruby runs the loop, it will assign a new value for the block parameter
i
, which will start at 0 and end at 9 (since we're running this loop 10
times):
10.times do |i|
puts "i is: #{i}"
end
# i is: 0
# i is: 1
# i is: 2
# i is: 3
# i is: 4
# i is: 5
# i is: 6
# i is: 7
# i is: 8
# i is: 9
In addition to the do
and end
syntax, Ruby also allows you to use curly
parentheses to define blocks. This syntax is commonly used for one-line blocks:
10.times { |i| puts "i is: #{i}" }
Ruby blocks are just about as important a feature of the Ruby language as callbacks are in JavaScript (and they serve similar purposes). They're an incredibly powerful tool, and you'll see them used in many different scenarios, including writing loops, so make sure to familiarize yourself with this syntax!
The last looping construct we'll discuss in Ruby is the #each
method. The
#each
method can be used with a few different data types, including arrays and
objects (as we'll see later), but one common use case for the #each
method is
to use it with a Range:
(1..20).each do |num|
puts num
end
This can be helpful for running a loop of a specified set of numbers, starting
with any value you like! Compare this to equivalent code in JavaScript using a
for
loop:
for (let i = 1; i <= 20; i++) {
console.log(i);
}
You can see how methods like #each
help us write cleaner code that more clearly
expresses our intent.
Time to get some practice! Write your code in the looping.rb
file. Run
learn test
to check your work. Your goal is to practice using control flow in
Ruby to familiarize yourself with the syntax. There is a JavaScript version of
the solution for each of these deliverables in the js/index.js
file you can
look at (but if you want an extra challenge, try solving them in Ruby without
looking at the JavaScript solution).
Write a method #happy_new_year
using a while
or until
loop that outputs
numbers starting at 10 and counting down to 1. After reaching 1, print out
"Happy New Year!"
happy_new_year
# => 10
# => 9
# => 8
# => ...
# => 1
# => Happy New Year!
Write a method #reverse_string
that takes one argument, a string, and reverses
it. Don't use the built-in .reverse
method. Instead, loop through the
characters in the input string and reverse it.
reverse_string("hello")
# => "olleh"
Write a method #fizzbuzz_printer
that prints the numbers from 1 to 100. For
multiples of three, print "Fizz" instead of the number and for the multiples
of five print "Buzz". For numbers which are multiples of both three and five,
print "FizzBuzz".
fizzbuzz
# 1
# 2
# Fizz
# 4
# Buzz
# Fizz
# 7
# ...
# 14
# FizzBuzz
# 16
# ...
# 100