Search code examples
rubyfibonaccioperator-precedence

Comma assignment (why right go first?) i.e. n,m = 1, 2?


In the process of figuring out blocks and yields I came across these comma-separated assignments:

def fibit 
  n,m =1,1
  loop do |variable|
    yield n
    n,m = m,n+m # this line
    puts "n is #{n} m is #{m}"
  end 
end

fibit do |num|
  puts "Next : #{num}"
  break if num > 100
end

Why does the m get assigned first in this scenario?

Does the last one always go first? If so why?

This was also seen as only e has the value of 1 meaning e went first?

e,r=1
puts r
puts "-------"
puts e

Also, does anyone have an idea why the code-block versions just executes, where if I write the same code with no code block I actually need to call the method for it to run?

def fibit 
  n,m =1,1
  loop do |variable|
    puts "Next : #{n}"
    break if n > 100
    n,m = m,n+m
  end 
end
fibit

If I didn't have the last line it wouldn't run. Where in the first one I don't actually call the fibit method? Or is the block kicking it off?


Solution

  • m does not get assigned first. When using multiple assignments, all right hand side calculations are done before any assignment to the left hand side.

    That's how this code works:

    a = 1
    b = 3
    
    a, b = b, a
    
    a
    # => 3
    b
    # => 1
    

    This would not be possible if the assignment was done serially, since you would get that both would be either equal 1 or 3.

    To further prove my point, simply swap the assignment of n and m in your code, and you'll find that the result is the same:

    def fibit 
    n,m =1,1
    loop do |variable|
        yield n
        m,n = n+m,m # this line
        puts "n is #{n} m is #{m}"
    end 
    end
    
    fibit do |num|
        puts "Next : #{num}"
        break if num > 100
    end