mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Document and test Enumerator.produce
Co-authored-by: Victor Shepelev <zverok.offline@gmail.com>
This commit is contained in:
parent
775037613b
commit
ac3e8834e0
2 changed files with 67 additions and 0 deletions
22
enumerator.c
22
enumerator.c
|
@ -2890,6 +2890,28 @@ producer_size(VALUE obj, VALUE args, VALUE eobj)
|
||||||
return DBL2NUM(HUGE_VAL);
|
return DBL2NUM(HUGE_VAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* Enumerator.produce(initial = nil) { |val| } -> enumerator
|
||||||
|
*
|
||||||
|
* Creates an infinite enumerator from any block, just called over and
|
||||||
|
* over. Result of the previous iteration is passed to the next one.
|
||||||
|
* If +initial+ is provided, it is passed to the first iteration, and
|
||||||
|
* becomes the first element of the enumerator; if it is not provided,
|
||||||
|
* first iteration receives +nil+, and its result becomes first
|
||||||
|
* element of the iterator.
|
||||||
|
*
|
||||||
|
* Raising StopIteration from the block stops an iteration.
|
||||||
|
*
|
||||||
|
* Examples of usage:
|
||||||
|
*
|
||||||
|
* Enumerator.produce(1, &:succ) # => enumerator of 1, 2, 3, 4, ....
|
||||||
|
*
|
||||||
|
* Enumerator.produce { rand(10) } # => infinite random number sequence
|
||||||
|
*
|
||||||
|
* ancestors = Enumerator.produce(node) { |prev| node = prev.parent or raise StopIteration }
|
||||||
|
* enclosing_section = ancestors.find { |n| n.type == :section }
|
||||||
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
enumerator_s_produce(int argc, VALUE *argv, VALUE klass)
|
enumerator_s_produce(int argc, VALUE *argv, VALUE klass)
|
||||||
{
|
{
|
||||||
|
|
|
@ -811,4 +811,49 @@ class TestEnumerator < Test::Unit::TestCase
|
||||||
e5.inspect
|
e5.inspect
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_produce
|
||||||
|
assert_raise(ArgumentError) { Enumerator.produce }
|
||||||
|
|
||||||
|
# Without initial object
|
||||||
|
passed_args = []
|
||||||
|
enum = Enumerator.produce { |obj| passed_args << obj; (obj || 0).succ }
|
||||||
|
assert_instance_of(Enumerator, enum)
|
||||||
|
assert_equal Float::INFINITY, enum.size
|
||||||
|
assert_equal [1, 2, 3], enum.take(3)
|
||||||
|
assert_equal [nil, 1, 2], passed_args
|
||||||
|
|
||||||
|
# With initial object
|
||||||
|
passed_args = []
|
||||||
|
enum = Enumerator.produce(1) { |obj| passed_args << obj; obj.succ }
|
||||||
|
assert_instance_of(Enumerator, enum)
|
||||||
|
assert_equal Float::INFINITY, enum.size
|
||||||
|
assert_equal [1, 2, 3], enum.take(3)
|
||||||
|
assert_equal [1, 2], passed_args
|
||||||
|
|
||||||
|
# Raising StopIteration
|
||||||
|
words = "The quick brown fox jumps over the lazy dog.".scan(/\w+/)
|
||||||
|
enum = Enumerator.produce { words.shift or raise StopIteration }
|
||||||
|
assert_equal Float::INFINITY, enum.size
|
||||||
|
assert_instance_of(Enumerator, enum)
|
||||||
|
assert_equal %w[The quick brown fox jumps over the lazy dog], enum.to_a
|
||||||
|
|
||||||
|
# Raising StopIteration
|
||||||
|
object = [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"]
|
||||||
|
enum = Enumerator.produce(object) { |obj|
|
||||||
|
obj.respond_to?(:first) or raise StopIteration
|
||||||
|
obj.first
|
||||||
|
}
|
||||||
|
assert_equal Float::INFINITY, enum.size
|
||||||
|
assert_instance_of(Enumerator, enum)
|
||||||
|
assert_nothing_raised {
|
||||||
|
assert_equal [
|
||||||
|
[[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"],
|
||||||
|
[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"],
|
||||||
|
[["abc", "def"], "ghi", "jkl"],
|
||||||
|
["abc", "def"],
|
||||||
|
"abc",
|
||||||
|
], enum.to_a
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue