ruby-changes:19659
From: drbrain <ko1@a...>
Date: Mon, 23 May 2011 08:33:27 +0900 (JST)
Subject: [ruby-changes:19659] drbrain:r31704 (trunk): * enumerator.c: Improve documentation. Patch by Dave Copeland.
drbrain 2011-05-23 08:33:21 +0900 (Mon, 23 May 2011) New Revision: 31704 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31704 Log: * enumerator.c: Improve documentation. Patch by Dave Copeland. [Ruby 1.9 - Bug #4757] Modified files: trunk/ChangeLog trunk/enumerator.c Index: ChangeLog =================================================================== --- ChangeLog (revision 31703) +++ ChangeLog (revision 31704) @@ -1,3 +1,8 @@ +Mon May 23 08:32:59 2011 Eric Hodel <drbrain@s...> + + * enumerator.c: Improve documentation. Patch by Dave Copeland. + [Ruby 1.9 - Bug #4757] + Mon May 23 07:19:45 2011 Martin Bosslet <Martin.Bosslet@g...> * NEWS (openssl): Infinite length support. Different behavior of Index: enumerator.c =================================================================== --- enumerator.c (revision 31703) +++ enumerator.c (revision 31704) @@ -17,33 +17,52 @@ /* * Document-class: Enumerator * - * A class which provides a method `each' to be used as an Enumerable - * object. + * A class which allows both internal and external iteration. * - * An enumerator can be created by following methods. + * An Enumerator can be created by the following methods. * - Kernel#to_enum * - Kernel#enum_for * - Enumerator.new * - * Also, most iteration methods without a block returns an enumerator. - * For example, Array#map returns an enumerator if a block is not given. - * The enumerator has the with_index method. - * So ary.map.with_index works as follows. + * Most methods have two forms: a block form where the contents + * are evaluated for each item in the enumeration, and a non-block form + * which returns a new Enumerator wrapping the iteration. * - * p %w[foo bar baz].map.with_index {|w,i| "#{i}:#{w}" } - * #=> ["0:foo", "1:bar", "2:baz"] + * enumerator = %w(one two three).each + * puts enumerator.class # => Enumerator + * enumerator.each_with_object("foo") do |item,obj| + * puts "#{obj}: #{item}" + * end + * # foo: one + * # foo: two + * # foo: three + * enum_with_obj = enumerator.each_with_object("foo") + * puts enum_with_obj.class # => Enumerator + * enum_with_obj.each do |item,obj| + * puts "#{obj: #{item}" + * end + * # foo: one + * # foo: two + * # foo: three * - * An enumerator object can be used as an external iterator. - * I.e. Enumerator#next returns the next value of the iterator. - * Enumerator#next raises StopIteration at end. + * This allows you to chain Enumerators together. For example, you + * can map a list's elements to strings containing the index + * and the element as a string via: * + * puts %w[foo bar baz].map.with_index {|w,i| "#{i}:#{w}" } + * # => ["0:foo", "1:bar", "2:baz"] + * + * An Enumerator can also be used as an external iterator. + * For example, Enumerator#next returns the next value of the iterator + * or raises StopIteration if the Enumerator is at the end. + * * e = [1,2,3].each # returns an enumerator object. - * p e.next #=> 1 - * p e.next #=> 2 - * p e.next #=> 3 - * p e.next #raises StopIteration + * puts e.next # => 1 + * puts e.next # => 2 + * puts e.next # => 3 + * puts e.next # raises StopIteration * - * An external iterator can be used to implement an internal iterator as follows. + * You can use this to implement an internal iterator as follows: * * def ext_each(e) * while true @@ -58,21 +77,22 @@ * end * * o = Object.new + * * def o.each - * p yield - * p yield(1) - * p yield(1, 2) + * puts yield + * puts yield(1) + * puts yield(1, 2) * 3 * end * * # use o.each as an internal iterator directly. - * p o.each {|*x| p x; [:b, *x] } - * #=> [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 + * puts o.each {|*x| puts x; [:b, *x] } + * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 * * # convert o.each to an external iterator for * # implementing an internal iterator. - * p ext_each(o.to_enum) {|*x| p x; [:b, *x] } - * #=> [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 + * puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] } + * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 * */ VALUE rb_cEnumerator; @@ -151,23 +171,32 @@ } /* - * call-seq: - * obj.to_enum(method = :each, *args) - * obj.enum_for(method = :each, *args) + * call-seq: + * obj.to_enum(method = :each, *args) + * obj.enum_for(method = :each, *args) * - * Returns Enumerator.new(self, method, *args). + * Creates a new Enumerator which will enumerate by on calling +method+ on + * +obj+. * - * e.g.: + * +method+:: the method to call on +obj+ to generate the enumeration + * +args+:: arguments that will be passed in +method+ <i>in addition</i> + * to the item itself. Note that the number of args + * must not exceed the number expected by +method+ * - * str = "xyz" + * === Example * - * enum = str.enum_for(:each_byte) - * a = enum.map {|b| '%02x' % b } #=> ["78", "79", "7a"] + * str = "xyz" * - * # protects an array from being modified - * a = [1, 2, 3] - * some_method(a.to_enum) + * enum = str.enum_for(:each_byte) + * enum.each { |b| puts b } + * # => 120 + * # => 121 + * # => 122 * + * # protect an array from being modified by some_method + * a = [1, 2, 3] + * some_method(a.to_enum) + * */ static VALUE obj_to_enum(int argc, VALUE *argv, VALUE obj) @@ -217,36 +246,38 @@ } /* - * call-seq: - * Enumerator.new(obj, method = :each, *args) - * Enumerator.new { |y| ... } + * call-seq: + * Enumerator.new { |yielder| ... } + * Enumerator.new(obj, method = :each, *args) * - * Creates a new Enumerator object, which is to be used as an - * Enumerable object iterating in a given way. + * Creates a new Enumerator object, which can be used as an + * Enumerable. * - * In the first form, a generated Enumerator iterates over the given - * object using the given method with the given arguments passed. - * Use of this form is discouraged. Use Kernel#enum_for(), alias - * to_enum, instead. + * In the first form, iteration is defined by the given block, in + * which a "yielder" object, given as block parameter, can be used to + * yield a value by calling the +yield+ method (aliased as +<<+): * - * e = Enumerator.new(ObjectSpace, :each_object) - * #-> ObjectSpace.enum_for(:each_object) + * fib = Enumerator.new do |y| + * a = b = 1 + * loop do + * y << a + * a, b = b, a + b + * end + * end * - * e.select { |obj| obj.is_a?(Class) } #=> array of all classes + * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] * - * In the second form, iteration is defined by the given block, in - * which a "yielder" object given as block parameter can be used to - * yield a value by calling the +yield+ method, alias +<<+. + * In the second, deprecated, form, a generated Enumerator iterates over the + * given object using the given method with the given arguments passed. * - * fib = Enumerator.new { |y| - * a = b = 1 - * loop { - * y << a - * a, b = b, a + b - * } - * } + * Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum + * instead. * - * p fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] + * e = Enumerator.new(ObjectSpace, :each_object) + * #-> ObjectSpace.enum_for(:each_object) + * + * e.select { |obj| obj.is_a?(Class) } #=> array of all classes + * */ static VALUE enumerator_initialize(int argc, VALUE *argv, VALUE obj) @@ -320,11 +351,11 @@ } /* - * call-seq: - * enum.each {...} + * call-seq: + * enum.each {...} * - * Iterates the given block using the object and the method specified - * in the first place. If no block is given, returns self. + * Iterates over the block according to how this Enumerable was constructed. + * If no block is given, returns self. * */ static VALUE @@ -350,13 +381,16 @@ } /* - * call-seq: - * e.with_index(offset = 0) {|(*args), idx| ... } - * e.with_index(offset = 0) + * call-seq: + * e.with_index(offset = 0) {|(*args), idx| ... } + * e.with_index(offset = 0) * - * Iterates the given block for each element with an index, which - * starts from +offset+. If no block is given, returns an enumerator. + * Iterates the given block for each element with an index, which + * starts from +offset+. If no block is given, returns a new Enumerator + * that includes the index, starting from +offset+ * + * +offset+:: the starting index to use + * */ static VALUE enumerator_with_index(int argc, VALUE *argv, VALUE obj) @@ -370,13 +404,14 @@ } /* - * call-seq: - * e.each_with_index {|(*args), idx| ... } - * e.each_with_index + * call-seq: + * e.each_with_index {|(*args), idx| ... } + * e.each_with_index * - * Same as Enumerator#with_index, except each_with_index does not - * receive an offset argument. + * Same as Enumerator#with_index(0), i.e. there is no starting offset. * + * If no block is given, a new Enumerator is returned that includes the index. + * */ static VALUE enumerator_each_with_index(VALUE obj) @@ -394,15 +429,31 @@ } /* - * call-seq: - * e.with_object(obj) {|(*args), memo_obj| ... } - * e.with_object(obj) + * call-seq: + * e.with_object(obj) {|(*args), obj| ... } + * e.with_object(obj) * - * Iterates the given block for each element with an arbitrary - * object given, and returns the initially given object. + * Iterates the given block for each element with an arbitrary object, +obj+, + * and returns +obj+ * - * If no block is given, returns an enumerator. + * If no block is given, returns a new Enumerator. * + * === Example + * + * to_three = Enumerator.new do |y| + * 3.times do |x| + * y << x + * end + * end + * + * to_three_with_string = to_three.with_object("foo") + * to_three_with_string.each do |x,string| + * puts "#{string}: #{x}" + * end + * + * # => foo:0 + * # => foo:1 + * # => foo:2 */ static VALUE enumerator_with_object(VALUE obj, VALUE memo) @@ -478,12 +529,15 @@ * call-seq: * e.next_values -> array * - * Returns the next object as an array in the enumerator, - * and move the internal position forward. - * When the position reached at the end, StopIteration is raised. + * Returns the next object as an array in the enumerator, and move the + * internal position forward. When the position reached at the end, + * StopIteration is raised. * - * This method can be used to distinguish <code>yield</code> and <code>yield nil</code>. + * This method can be used to distinguish <code>yield</code> and <code>yield + * nil</code>. * + * === Example + * * o = Object.new * def o.each * yield @@ -512,9 +566,9 @@ * # yield nil [nil] nil * # yield [1, 2] [[1, 2]] [1, 2] * - * Note that enumeration sequence by next_values method does not affect other - * non-external enumeration methods, unless underlying iteration - * methods itself has side-effect, e.g. IO#each_line. + * Note that enumeration sequenced by +next_values+ does not affect other + * non-external enumeration methods, unless underlying iteration methods + * itself has side-effect, e.g. IO#each_line. * */ @@ -557,10 +611,11 @@ * call-seq: * e.next -> object * - * Returns the next object in the enumerator, and move the internal - * position forward. When the position reached at the end, StopIteration - * is raised. + * Returns the next object in the enumerator, and move the internal position + * forward. When the position reached at the end, StopIteration is raised. * + * === Example + * * a = [1,2,3] * e = a.to_enum * p e.next #=> 1 @@ -568,9 +623,9 @@ * p e.next #=> 3 * p e.next #raises StopIteration * - * Note that enumeration sequence by next method does not affect other - * non-external enumeration methods, unless underlying iteration - * methods itself has side-effect, e.g. IO#each_line. + * Note that enumeration sequence by +next+ does not affect other non-external + * enumeration methods, unless the underlying iteration methods itself has + * side-effect, e.g. IO#each_line. * */ @@ -596,10 +651,12 @@ * call-seq: * e.peek_values -> array * - * Returns the next object as an array in the enumerator, - * but don't move the internal position forward. - * When the position reached at the end, StopIteration is raised. + * Returns the next object as an array, similar to Enumerator#next_values, but + * doesn't move the internal position forward. If the position is already at + * the end, StopIteration is raised. * + * === Example + * * o = Object.new * def o.each * yield @@ -628,10 +685,12 @@ * call-seq: * e.peek -> object * - * Returns the next object in the enumerator, but don't move the internal - * position forward. When the position reached at the end, StopIteration + * Returns the next object in the enumerator, but doesn't move the internal + * position forward. If the position is already at the end, StopIteration * is raised. * + * === Example + * * a = [1,2,3] * e = a.to_enum * p e.next #=> 1 @@ -655,38 +714,26 @@ * call-seq: * e.feed obj -> nil * - * Set the value for the next yield in the enumerator returns. + * Set the value to be returned by the next call to +yield+ by the enumerator. + * If the value is not set, the +yield+ returns +nil+ and the value is cleared + * after it is used the first time. * - * If the value is not set, the yield returns nil. + * +obj+:: the object to return from the next call to the Enumerator's +yield+ * - * This value is cleared after used. + * === Example * - * o = Object.new - * def o.each - * # (2) - * x = yield - * p x #=> "foo" - * # (5) - * x = yield - * p x #=> nil - * # (7) - * x = yield - * # not reached - * p x + * three_times = Enumerator.new do |yielder| + * 3.times do |x| + * result = yielder.yield(x) + * puts result + * end * end - * e = o.to_enum - * # (1) - * e.next - * # (3) - * e.feed "foo" - * # (4) - * e.next - * # (6) - * e.next - * # (8) * + * three_times.next # => 0 + * three_times.feed("foo") + * three_times.next # => 1, prints "foo" + * three_times.next # => 2, prints nothing */ - static VALUE enumerator_feed(VALUE obj, VALUE v) { @@ -704,7 +751,7 @@ * call-seq: * e.rewind -> e * - * Rewinds the enumeration sequence by the next method. + * Rewinds the enumeration sequence by one step. * * If the enclosed object responds to a "rewind" method, it is called. */ @@ -785,7 +832,7 @@ * call-seq: * e.inspect -> string * - * Create a printable version of <i>e</i>. + * Creates a printable version of <i>e</i>. */ static VALUE @@ -1027,27 +1074,27 @@ } /* - * Document-class: StopIteration + * Document-class: StopIteration * - * Raised to stop the iteration, in particular by Enumerator#next. It is - * rescued by Kernel#loop. + * Raised to stop the iteration, in particular by Enumerator#next. It is + * rescued by Kernel#loop. * - * loop do - * puts "Hello" - * raise StopIteration - * puts "World" - * end - * puts "Done!" + * loop do + * puts "Hello" + * raise StopIteration + * puts "World" + * end + * puts "Done!" * - * <em>produces:</em> + * <em>produces:</em> * - * Hello - * Done! + * Hello + * Done! */ /* * call-seq: - * stopiteration.result -> value + * result -> value * * Returns the return value of the iterator. * @@ -1058,14 +1105,17 @@ * yield 3 * 100 * end + * * e = o.to_enum - * p e.next #=> 1 - * p e.next #=> 2 - * p e.next #=> 3 + * + * puts e.next #=> 1 + * puts e.next #=> 2 + * puts e.next #=> 3 + * * begin * e.next - * rescue StopIteration - * p $!.result #=> 100 + * rescue StopIteration => ex + * puts ex.result #=> 100 * end * */ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/