# Ringo Starr and the Fibonacci Sequence: Multiple Assignments in Ruby

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.