When is the Enumerator::Yielder#yield method useful?

前端 未结 4 945
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-13 12:03

The question \"Meaning of the word yield\" mentions the Enumerator::Yielder#yield method. I haven\'t used it before, and wonder under what circumstances it would be

4条回答
  •  粉色の甜心
    2021-02-13 12:09

    "How to create an infinite enumerable of Times?" talks about constructing and lazy iterators, but my favorite usage is wrapping an existing Enumerable with additional functionality (any enumerable, without needing to know what it really is, whether it's infinite or not etc).

    A trivial example would be implementing the each_with_index method (or, more generally, with_index method):

    module Enumerable
      def my_with_index
        Enumerator.new do |yielder|
          i = 0
          self.each do |e|
            yielder.yield e, i
            i += 1
          end
        end
      end
    
      def my_each_with_index
        self.my_with_index.each do |e, i|
          yield e, i
        end
      end
    end
    
    [:foo, :bar, :baz].my_each_with_index do |e,i|
      puts "#{i}: #{e}"
    end
    #=>0: foo
    #=>1: bar
    #=>2: baz
    

    Extending to something not already implemented in the core library, such as cyclically assigning value from a given array to each enumerable element (say, for coloring table rows):

    module Enumerable
      def with_cycle values
        Enumerator.new do |yielder|
          self.each do |e|
            v = values.shift
            yielder.yield e, v
            values.push v
          end
        end
      end
    end
    
    p (1..10).with_cycle([:red, :green, :blue]).to_a # works with any Enumerable, such as Range
    #=>[[1, :red], [2, :green], [3, :blue], [4, :red], [5, :green], [6, :blue], [7, :red], [8, :green], [9, :blue], [10, :red]]
    

    The whole point is that these methods return an Enumerator, which you then combine with the usual Enumerable methods, such as select, map, inject etc.

提交回复
热议问题