diff options
author | Tanaka Akira <[email protected]> | 2025-04-22 01:49:41 +0900 |
---|---|---|
committer | Tanaka Akira <[email protected]> | 2025-04-22 01:49:41 +0900 |
commit | fa17cb75a1a79b6c3fb1e70acc5a4a589efa23e8 (patch) | |
tree | 0fe77e11df76b6eb51063f5e044f76653c4e4c8d /enum.c | |
parent | ff689b9a7ac01d512619e28cd832271f85295e6a (diff) |
[doc] update Enumerable document.
- Enhance document about #size method for Enumerable and Enumerator
- add an Enumerator example for Enumerable#drop_while
Diffstat (limited to 'enum.c')
-rw-r--r-- | enum.c | 83 |
1 files changed, 63 insertions, 20 deletions
@@ -3704,6 +3704,17 @@ drop_while_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args)) * * With no block given, returns an Enumerator. * + * e = (1..4).drop_while + * p e #=> #<Enumerator: 1..4:drop_while> + * i = e.next; p i; e.feed(i < 3) #=> 1 + * i = e.next; p i; e.feed(i < 3) #=> 2 + * i = e.next; p i; e.feed(i < 3) #=> 3 + * begin + * e.next + * rescue StopIteration + * p $!.result #=> [3, 4] + * end + * */ static VALUE @@ -5115,11 +5126,34 @@ enum_compact(VALUE obj) * * === #size * - * \Enumerator has #size method. - * It uses the size function argument for +Enumerator.new+. - * It should returns the number of iterations (number of #each method yields). - * The result is integer or +Float::INFINITY+. - * However it may also return nil when it is difficult to determine the result. + * \Enumerator has a #size method. + * It uses the size function argument passed to +Enumerator.new+. + * + * e = Enumerator.new(-> { 3 }) {|y| p y; y.yield :a; y.yield :b; y.yield :c; :z } + * p e.size #=> 3 + * p e.next #=> :a + * p e.next #=> :b + * p e.next #=> :c + * begin + * e.next + * rescue StopIteration + * p $!.result #=> :z + * end + * + * The result of the size function should represent the number of iterations + * (i.e., the number of times Enumerator::Yielder#yield is called). + * In the above example, the block calls #yield three times, and + * the size function, +-> { 3 }+, returns 3 accordingly. + * The result of the size function can be an integer, +Float::INFINITY+, + * or +nil+. + * An integer means the exact number of times #yield will be called, + * as shown above. + * +Float::INFINITY+ indicates an infinite number of #yield calls. + * +nil+ means the number of #yield calls is difficult or impossible to + * determine. + * + * Many iteration methods return an \Enumerator object with an + * appropriate size function if no block is given. * * Examples: * @@ -5127,30 +5161,39 @@ enum_compact(VALUE obj) * {a: "x", b: "y", c: "z"}.each.size #=> 3 * (0..20).to_a.permutation.size #=> 51090942171709440000 * loop.size #=> Float::INFINITY - * (1..100).drop_while.size #=> nil # the size depends on the block values - * File.open("/etc/resolv.conf").each.size #=> nil # not computable without actually read the file. + * (1..100).drop_while.size #=> nil # size depends on the block's behavior + * STDIN.each.size #=> nil # cannot be computed without consuming input + * File.open("/etc/resolv.conf").each.size #=> nil # cannot be computed without reading the file * - * The behavior of #size of Range-based enumerator depends on the #begin element. - - * * If the #begin element is an integer, #size methd returns integer or +Float::INFINITY+. - * * If the #begin element is an object with #succ method except integer, #size methd returns nil. - * (It is too slow to compute the size by calling #succ repeatedly) - * * If the #begin element is an object without #succ method, #size method raises TypeError. + * The behavior of #size for Range-based enumerators depends on the #begin element: + * + * - If the #begin element is an Integer, the #size method returns an Integer or +Float::INFINITY+. + * - If the #begin element is an object with a #succ method (other than Integer), #size returns +nil+. + * (Computing the size would require repeatedly calling #succ, which may be too slow.) + * - If the #begin element does not have a #succ method, #size raises a TypeError. * * Examples: * * (10..42).each.size #=> 33 - * (10..42.9).each.size #=> 33 (#end element can be numeric other than integer) + * (10..42.9).each.size #=> 33 (the #end element may be a non-integer numeric) * (10..).each.size #=> Float::INFINITY * ("a".."z").each.size #=> nil * ("a"..).each.size #=> nil - * (1.0..9.0).each.size # raises TypeError (There is no Float#succ) - * (..10).each.size # raises TypeError (beginless range has nil as #begin element) + * (1.0..9.0).each.size # raises TypeError (Float does not have #succ) + * (..10).each.size # raises TypeError (beginless range has nil as its #begin) + * + * The \Enumerable module itself does not define a #size method. + * A class that includes \Enumerable may define its own #size method. + * It is recommended that such a #size method be consistent with + * Enumerator#size. + * + * Array and Hash implement #size and return values consistent with + * Enumerator#size. + * IO and Dir do not define #size, which is also consistent because the + * corresponding enumerator's size function returns +nil+. * - * \Enumerable classes may have #size method. - * It returns the result same as Enumerator#size in most cases: Array, Hash. - * Some classes have no #size method: IO, Dir. - * (Note that File#size is not related to File#each. It returns nubmer of bytes instead of number of lines.) + * However, it is not strictly required for a class's #size method to match Enumerator#size. + * For example, File#size returns the number of bytes in the file, not the number of lines. * */ |