Search code examples
rubyconcurrencyfibers

Fiber.yield using ||


I would like some help with the following code:

sg = Fiber.new do
    s = 0
    loop do
        square = s * s
        s += 1
        s = Fiber.yield(square) || s
    end
end

puts sg.resume
puts sg.resume
puts sg.resume
puts sg.resume 40
puts sg.resume
puts sg.resume 0
puts sg.resume
puts sg.resume

When run, outputs:

0
1
4
1600
1681
0
1
4

How does line 6 s = Fiber.yield(square) || s work? I think I understand the component parts just not what the line as a whole is doing. (Is there an alternative way of writing this that might better help me understand?).

(Edit: This code is a very slightly modified example from page 295 'Beginning Ruby, From Novice to Professional 2nd Ed' by Peter Cooper.)


Solution

  • According to the docs for yield

    Any arguments passed to the next resume will be the value that this Fiber.yield expression evaluates to.

    The line

    s = Fiber.yield(square) || s
    

    assigns the argument passed to resume to s. If that value is nil (or the argument is missing), s is re-assiged to s (i.e. it doesn't change).

    Example:

    sg.resume       #=> s = nil || s
                    #=> s = s
    
    sg.resume 40    #=> s = 40  || s
                    #=> s = 40
    

    Another way to write it is:

    result = Fiber.yield(square)
    s = result if result