Sandwich Scheduling: a look at Ruby's Array cycle method
- By Tim Ash
- 28 September
How Ruby can help you schedule your sandwiches
How Ruby code can be refactored using multiple assignments.
Ruby allows more than one variable to be assigned at a time. This post will explore some of the situations where this can be helpful and also warn you of a potential pitfall.
One use of multiple assignment is to simply do in one line what would otherwise be done in two or more. Instead of:
drummer = "Ringo Starr"
bassist = "Cliff Burton"
guitarist = "Jimi Hendrix"
you can write:
drummer, bassist, guitarist = "Ringo Starr", "Cliff Burton", "Jimi Hendrix"
You can also swap values without having to use an intermediate variable, so if you think Jimi Hendrix should play the drums while Ringo Starr plays the guitar, instead of:
intermediate = drummer
drummer = guitarist
guitarist = intermediate
you can write:
drummer, guitarist = guitarist, drummer
However, if you want Mick Jagger to both sing and play the bongos, you may run into the potential pitfall I warned you about above. At first you might think that the following would set both variables to the same value:
singer, bongos = "Mick Jagger"
Instead this will set the singer
variable to "Mick Jagger"
, and the bongos
variable to nil
.
As a demonstration of how multiple assignment can be used when refactoring code, let’s take a look at the following function I found on Stack Overflow (original post here):
def fib (n)
return 0 if n == 0
x = 0
y = 1
(1..n).each do
z = (x + y)
x = y
y = z
end
return y
end
This function calculates the nth value of the Fibonacci sequence, where each term is the sum of the two preceding terms. The first thing I notice is that the two lines where x
and y
are initialised can be combined into a single line:
def fib (n)
return 0 if n == 0
x, y = 0, 1
(1..n).each do
z = (x + y)
x = y
y = z
end
return y
end
This saves a line of code, but also notice we’re using an intermediate variable, z
, when setting x
and y
in the each loop. We can refactor this to:
def fib (n)
return 0 if n == 0
x, y = 0, 1
(1..n).each do
x, y = y, (x + y)
end
return y
end
which saves another two lines of code and eliminates the intermediate variable. Getting rid of the intermediate variable also improves the efficiency of the code, as there’s now one less variable to be held in memory and for the garbage collector to deal with when we’re finished.
Now that the each loop contains only one statement, I’d be tempted to refactor it to:
def fib (n)
return 0 if n == 0
x, y = 0, 1
(1..n).each { x, y = y, (x + y) }
return y
end
for a total saving of five lines of code and a variable, over our original function.
Please let me know the uses you’ve put multiple assignments to - why not leave a comment below?
How Ruby can help you schedule your sandwiches
Another way Ruby can help you keep track of your lockdown exercise routine
How Ruby can help you keep track of your lockdown exercise routine
How Ruby can help you mix the drinks and bust some moves at the charity ball
You won't believe what happens when all the animals run away from the zoo.
Home, home on the Range, where the Ewoks and the Wookies play
We would love to hear from you so let's get in touch!