This is a Ruby tree! It shows every object from the Ruby Programming Language in a tree format.

transfer

        # Fiber.transfer

(from ruby core)
---
    fiber.transfer(args, ...) -> obj

---

Transfer control to another fiber, resuming it from where it last
stopped or starting it if it was not resumed before. The calling fiber
will be suspended much like in a call to Fiber.yield.

The fiber which receives the transfer call treats it much like a resume
call. Arguments passed to transfer are treated like those passed to
resume.

The two style of control passing to and from fiber (one is #resume and
Fiber::yield, another is #transfer to and from fiber) can't be freely
mixed.

*   If the Fiber's lifecycle had started with transfer, it will never be
    able to yield or be resumed control passing, only finish or transfer
    back. (It still can resume other fibers that are allowed to be
    resumed.)
*   If the Fiber's lifecycle had started with resume, it can yield or
    transfer to another Fiber, but can receive control back only the way
    compatible with the way it was given away: if it had transferred, it
    only can be transferred back, and if it had yielded, it only can be
    resumed back. After that, it again can transfer or yield.


If those rules are broken FiberError is raised.

For an individual Fiber design, yield/resume is easier to use (the Fiber
just gives away control, it doesn't need to think about who the control
is given to), while transfer is more flexible for complex cases,
allowing to build arbitrary graphs of Fibers dependent on each other.

Example:

    manager = nil # For local var to be visible inside worker block

    # This fiber would be started with transfer
    # It can't yield, and can't be resumed
    worker = Fiber.new { |work|
      puts "Worker: starts"
      puts "Worker: Performed #{work.inspect}, transferring back"
      # Fiber.yield     # this would raise FiberError: attempt to yield on a not resumed fiber
      # manager.resume  # this would raise FiberError: attempt to resume a resumed fiber (double resume)
      manager.transfer(work.capitalize)
    }

    # This fiber would be started with resume
    # It can yield or transfer, and can be transferred
    # back or resumed
    manager = Fiber.new {
      puts "Manager: starts"
      puts "Manager: transferring 'something' to worker"
      result = worker.transfer('something')
      puts "Manager: worker returned #{result.inspect}"
      # worker.resume    # this would raise FiberError: attempt to resume a transferring fiber
      Fiber.yield        # this is OK, the fiber transferred from and to, now it can yield
      puts "Manager: finished"
    }

    puts "Starting the manager"
    manager.resume
    puts "Resuming the manager"
    # manager.transfer  # this would raise FiberError: attempt to transfer to a yielding fiber
    manager.resume

*produces*

    Starting the manager
    Manager: starts
    Manager: transferring 'something' to worker
    Worker: starts
    Worker: Performed "something", transferring back
    Manager: worker returned "Something"
    Resuming the manager
    Manager: finished



      

This is MURDOC! A Ruby documentation browser inspired by Smalltalk-80. It allows you to learn about Ruby by browsing through its class hierarchies, and see any of its methods.