2

I came across a ruby method that was an iterative fibonacci sequence.(not recursion) There is a line in the code that I've never seen before and I'm not exactly sure what it is doing. Here is the method:

METHOD:

def practice(n)
  return 0 if n == 0
  num1 = 2
  num2 = 1
  n.times do
    num1, num2 = num2, (num1 + num2)
  end
  num1
end 

If someone could iterate though this and explain what is happening I would be forever thankful. But, mainly I don't understand this part of the code -

n.times do
  num1, num2 = num2, (num1 + num2)
end

What does the num1, num2 = num2 do/mean??

2 Answers 2

3

The line of code num1, num2 = num2, (num1 + num2) is assigning two variables at once. num1 gets the old value of num2, while num2 gets the new value (num1 + num2).

Having multiple assignments on a single line of code allows you to do both operations without needing to use a temporary variable. For example, this won't work:

num1 = num2
num2 = (num1 + num2)

because num1 has been overwritten with a new value before the addition step, so num2 will be assigned the wrong value. The one-line version is equivalent to:

temp = (num1 + num2)
num1 = num2
num2 = temp

For reference, this is called parallel assignment or sometimes multiple assignment.

Sign up to request clarification or add additional context in comments.

6 Comments

AHHH I see! Thank you
A niggly: "assigning two variables at once" is not quite right, as Ruby is creating temporary variables under the covers.
@CarySwoveland It doesn't matter what Ruby is doing under the covers. That's why the abstraction exists.
@CarySwoveland: I'm pretty sure that no Ruby implementation does this. The spec says that the right-hand side is wrapped in an array, and then it's just normal array destructuring. But at least the JRuby compiler eliminates the intermediate array and manipulates the variables directly on the stack (which after JVM compilation probably ends up as direct swapping of registers). No variables involved. In fact, I wouldn't be too surprised to find out that JRuby in combination with Truffle, Graal, and HotSpot's C2 compiler, is able to eliminate at least num2 completely.
@Jörg, is the array not a temporary variable? (But no, that's not what I meant.) My point was that the wording, "assigning two variables at once", could be improved, and as I said, that's a very minor point.
|
2

(I don't know what it's its official name in Ruby but) It is parallel assignment.

num1 is assigned the value of num2, num2 is assigned the value of num1 + num2 and both assignments happen on the same time.

  +------------+
  v            |
num1, num2 = num2, (num1 + num2)
        ^                |
        +----------------+

Technically, it is the same as:

temp1 = num2
temp2 = num1 + num2
num1 = temp1
num2 = temp2

I.e. both right-hand side expressions are computed before doing the assignments. This way, after the assignment num1 gets the old value of num2 and num2 gets the old value of num1 + num2 (read "old" like "before assignment").

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.