Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel Assignment operator in Ruby

Tags:

ruby

I was going through an example from the Programming in Ruby book:

def fib_up_to(max)
  i1, i2 = 1, 1 # parallel assignment (i1 = 1 and i2 = 1)
  while i1 <= max
    yield i1
    i1, i2 = i2, i1+i2
  end
end
fib_up_to(100) {|f| print f, " " }

This simply prints the Fibonacci numbers up to 100. That's fine. When I replace the parallel assignment with:

i1 = i2
i2 = i1+i2

I am not getting the desired output.

Is it advisable to use parallel assignments? I come from a Java background and it feels really weird to see this type of assignment.

One more question is: Is parallel assignment an operator?

like image 692
bragboy Avatar asked May 24 '10 09:05

bragboy


People also ask

What is an assignment operator in Ruby?

Ruby Assignment Operators Add AND assignment operator, adds right operand to the left operand and assign the result to left operand. c += a is equivalent to c = c + a. -= Subtract AND assignment operator, subtracts right operand from the left operand and assign the result to left operand.

What is ||= in Ruby?

In ruby 'a ||= b' is called "or - equal" operator. It is a short way of saying if a has a boolean value of true(if it is neither false or nil) it has the value of a. If not it has the value of b.

What does << do in Ruby?

It means add to the end (append).

How do you assign a value in Ruby?

In Ruby assignment operator is done using the equal operator "=". This is applicable both for variables and objects, as strings, floats, and integers are actually objects in Ruby, you're always assigning objects.


1 Answers

The problem with doing the assignment in 2 separate statements is that i2 = i1 + i2 will then use the new value of i1 rather than the previous value required to correctly generate the Fibonacci sequence.

When you use parallel assignment all of the expressions on the right hand side are evaluated first and then assigned to the receiving variables on the left hand side.

Parallel assignment isn't a special operator. Essentially what is on the right hand side acts as an Array where if we list multiple variables on the left hand side then the array is unpacked and assigned into the respective variables.

Here are some more examples:

irb(main):020:0> a = 1, 2 # assign to a single variable
=> [1, 2]
irb(main):021:0> a
=> [1, 2]
irb(main):022:0> a, b = 1, 2 # unpack into separate variables
=> [1, 2]
irb(main):023:0> a
=> 1
irb(main):024:0> b
=> 2
irb(main):025:0> a, b = [1, 2, 3] # 3 is 'lost' as no receiving variable
=> [1, 2, 3]
irb(main):026:0> a
=> 1
irb(main):027:0> b
=> 2
irb(main):028:0> first, *rest = [1, 2, 3] # *rest consumes the remaining elements
=> [1, 2, 3]
irb(main):029:0> first
=> 1
irb(main):030:0> rest
=> [2, 3]

It is a useful feature of ruby, for example it facilitates having methods that return multiple values e.g.

def sum_and_difference(a, b)
  a + b, a - b
end

sum, difference = sum_and_difference 5, 3

In Java the closest thing would be to have a method that returned int[] but if we wanted to return a string and a number we'd need to create a little POJO to act as struct for the return value or return Object[] and clutter the code up with casts. See this other question that I answered recently for a more practical example.

like image 94
mikej Avatar answered Sep 18 '22 13:09

mikej