From a7ddb2e342a909cef7d1a73fcc1d0ba193654e35 Mon Sep 17 00:00:00 2001 From: knu Date: Fri, 17 Oct 2003 14:01:26 +0000 Subject: * lib/generator.rb: Add rdoc documentation. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4797 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/generator.rb | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/generator.rb b/lib/generator.rb index 7e49f3cda0..196fc8f483 100644 --- a/lib/generator.rb +++ b/lib/generator.rb @@ -1,5 +1,7 @@ #!/usr/bin/env ruby # +# generator.rb - converts an internal iterator to an external iterator +#++ # Copyright (c) 2001,2003 Akinori MUSHA # # All rights reserved. You can redistribute and/or modify it under @@ -8,14 +10,60 @@ # $Idaemons: /home/cvs/rb/generator.rb,v 1.8 2001/10/03 08:54:32 knu Exp $ # $RoughId: generator.rb,v 1.10 2003/10/14 19:36:58 knu Exp $ # $Id$ - # -# class Generator - converts an internal iterator to an external iterator +# == Overview +# +# This library provides the Generator class, which converts an +# internal iterator (i.e. an Enumerable object) to an external +# iterator. In that form, you can roll many iterators independently. +# +# The SyncEnumerator class, which is implemented using Generator, +# makes it easy to roll many Enumerable objects synchronously. # +# See the respective classes for examples of usage. +# +# Generator converts an internal iterator (i.e. an Enumerable object) +# to an external iterator. +# +# Note that it is not very fast since it is implemented using +# continuation, which currently is slow. +# +# == Example +# +# require 'generator' +# +# # Generator from an Enumerable object +# g = Generator.new(['A', 'B', 'C', 'Z']) +# +# while g.next? +# puts g.next +# end +# +# # Generator from a block +# g = Generator.new { |g| +# for i in 'A'..'C' +# g.yield i +# end +# +# g.yield 'Z' +# } +# +# # The same result as above +# while g.next? +# puts g.next +# end +# class Generator include Enumerable + # Creates a new generator either from an Enumerable object or from a + # block. + # + # In the former, block is ignored even if given. + # + # In the latter, the given block is called with the generator + # itself, and expected to call the +yield+ method for each element. def initialize(enum = nil, &block) if enum @block = proc { |g| @@ -38,6 +86,7 @@ class Generator self end + # Yields an element to the generator. def yield(value) if @cont_yield = callcc { |c| c } @queue << value @@ -47,6 +96,7 @@ class Generator self end + # Returns true if the generator has reached the end. def end?() if @cont_endp = callcc { |c| c } @cont_yield.nil? && @queue.empty? @@ -55,18 +105,22 @@ class Generator end end + # Returns true if the generator has not reached the end yet. def next?() !end? end + # Returns the current index (position) counting from zero. def index() @index end + # Returns the current index (position) counting from zero. def pos() @index end + # Returns the element at the current position and moves forward. def next() if end? raise EOFError, "no more element is supplied" @@ -81,6 +135,7 @@ class Generator @queue.shift end + # Returns the element at the current position. def current() if @queue.empty? raise EOFError, "no more element is supplied" @@ -89,12 +144,14 @@ class Generator @queue.first end + # Rewinds the generator. def rewind() initialize(nil, &@block) if @index.nonzero? self end + # Rewinds the generator and enumerates the elements. def each rewind @@ -107,24 +164,42 @@ class Generator end # -# class SyncEnumerator - enumerates multiple internal iterators synchronously +# SyncEnumerator creates an Enumerable object from multiple Enumerable +# objects and enumerates them synchronously. +# +# == Example +# +# require 'generator' +# +# s = SyncEnumerator.new([1,2,3], ['a', 'b', 'c']) +# +# # Yields [1, 'a'], [2, 'b'], and [3,'c'] +# s.each { |row| puts row.join(', ') } # - class SyncEnumerator include Enumerable + # Creates a new SyncEnumerator which enumerates rows of given + # Enumerable objects. def initialize(*enums) @gens = enums.map { |e| Generator.new(e) } end + # Returns the number of enumerated Enumerable objects, i.e. the size + # of each row. def size @gens.size end + # Returns the number of enumerated Enumerable objects, i.e. the size + # of each row. def length @gens.length end + # Returns true if the given nth Enumerable object has reached the + # end. If no argument is given, returns true if any of the + # Enumerable objects has reached the end. def end?(i = nil) if i.nil? @gens.detect { |g| g.end? } ? true : false @@ -133,6 +208,7 @@ class SyncEnumerator end end + # Enumerates rows of the Enumerable objects. def each @gens.each { |g| g.rewind } -- cgit v1.2.3