Enumerator as an infinite generator in Ruby

前端 未结 4 969
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-05 04:45

I\'m reading one resource explaining how Enumerators can be used as generators, which as an example like:

triangular_numbers = Enumerator.new do |yielder|
  numb         


        
4条回答
  •  深忆病人
    2021-02-05 05:18

    The Yielder is just a piece of code that returns the value and wait until the next call.

    This can be easily achieve by using the Ruby Fiber Class. See the following example that creates a SimpleEnumerator class:

    class SimpleEnumerator
    
      def initialize &block
        # creates a new Fiber to be used as an Yielder
        @yielder  = Fiber.new do
          yield Fiber # call the block code. The same as: block.call Fiber
          raise StopIteration # raise an error if there is no more calls
        end
      end
    
      def next
        # return the value and wait until the next call
        @yielder.resume
      end
    
    end
    
    triangular_numbers = SimpleEnumerator.new do |yielder|
      number  = 0
      count   = 1
      loop do
        number  += count
        count   += 1
        yielder.yield number
      end
    end
    
    print triangular_numbers.next, " " 
    print triangular_numbers.next, " " 
    print triangular_numbers.next, " " 
    

    I just replaced Enumerator.new in your code by SimpleEnumerator.new and the results are the same.

    There is a "light weight cooperative concurrency"; using the Ruby documentation words, where the programmer schedules what should be done, in other words, the programmer can pause and resume the code block.

提交回复
热议问题