Parallel Assignment operator in Ruby

前端 未结 2 740

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 <         


        
相关标签:
2条回答
  • 2020-12-01 06:10

    I was reading the same thing and had the same question. It would be less confusing and make more sense if it had been written like this:

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

    Using i1, i2 = 1, 1 doesn't make sense in my opinion. But that type of assignment does makes sense for line 5.

    0 讨论(0)
  • 2020-12-01 06:13

    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.

    0 讨论(0)
提交回复
热议问题