Feature #707 [ruby-core:19679]

Documentation for Enumerator chaining

Added by Brian Candler 633 days ago. Updated 607 days ago.

Status :Open Start :11/03/2008
Priority :Low Due date :
Assigned to :Yukihiro Matsumoto % Done :

0%

Category :DOC
Target version :1.9.x

Description

Enumerators now support a horizontal filter/chaining pattern:

  generator.filter1 { ... }.filter2 { ... }.filter3 { ... }.consumer

The overall pattern for a filter is:

  Enumerator.new do |y|
    source.each do |input|     # filter INPUT
      ...
      y << output              # filter OUTPUT
    end
  end

This is extremely powerful. However it is not obvious to the newcomer that this is even possible. (Confusion may arise where people know Ruby 1.8's Enumerator, which cannot do this)

So I would just like to see this pattern documented with an example, e.g. under ri Enumerator.new

I have attached a possible example. Note that I have written my Fib generator in a style familiar from ruby-1.8, to emphasise that the Enumerator filter doesn't require a specially-written generator.

fib.rb (676 Bytes) Brian Candler, 11/03/2008 06:41 PM

History

11/04/2008 12:05 AM - Brian Candler

Here is another (shorter and simpler)

class Enumerator
  def filter(&blk)
    self.class.new do |y|
      each do |*input|
        blk.call(y, *input)
      end
    end
  end
end

a = (1..1_000_000_000).to_enum
a.filter { |out,inp| out << inp if inp % 2 == 0 }.
  filter { |out,inp| out << inp+100 }.
  with_index.each { |inp,c| puts inp; break if c > 10 }

11/29/2008 04:29 PM - Koichi Sasada

  • Assigned to set to Yukihiro Matsumoto

11/14/2009 03:04 AM - Roger Pack

11/14/2009 05:01 AM - Brian Candler

> Is this also possible in 1.8?

Sure. Block-form Enumerator is surprisingly straightforward to implement, see
http://github.com/trans/facets/blob/master/lib/more/facets/enumerator.rb

But since 1.9 has it already, I think it's worth documenting the possibilities more clearly.

Also available in: Atom PDF