Skip to content

Commit

Permalink
core: Add Enumerator.produce
Browse files Browse the repository at this point in the history
Add the signature for Enumerator.produce
https://bugs.ruby-lang.org/issues/14781
  • Loading branch information
tk0miya committed Sep 11, 2023
1 parent db9be2e commit f3acb2a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
37 changes: 37 additions & 0 deletions core/enumerator.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,43 @@
class Enumerator[unchecked out Elem, out Return] < Object
include Enumerable[Elem]

# <!--
# rdoc-file=enumerator.c
# - Enumerator.produce(initial = nil) { |prev| block } -> enumerator
# -->
#
# Creates an infinite enumerator from any block, just called over and
# over. The 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,
# the first iteration receives +nil+, and its result becomes the first
# element of the iterator.
#
# Raising StopIteration from the block stops an iteration.
#
# 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 }
#
# Using ::produce together with Enumerable methods like Enumerable#detect,
# Enumerable#slice_after, Enumerable#take_while can provide Enumerator-based alternatives
# for +while+ and +until+ cycles:
#
# # Find next Tuesday
# require "date"
# Enumerator.produce(Date.today, &:succ).detect(&:tuesday?)
#
# # Simple lexer:
# require "strscan"
# scanner = StringScanner.new("7+38/6")
# PATTERN = %r{\d+|[-/+*]}
# Enumerator.produce { scanner.scan(PATTERN) }.slice_after { scanner.eos? }.first
# # => ["7", "+", "38", "/", "6"]
def self.produce: (?untyped initial) { (untyped) -> untyped } -> self

# <!--
# rdoc-file=enumerator.c
# - Enumerator.product(*enums) -> enumerator
Expand Down
7 changes: 7 additions & 0 deletions test/stdlib/Enumerator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ class EnumeratorSingletonTest < Test::Unit::TestCase

testing "singleton(::Enumerator)"

def test_produce
assert_send_type(
"(?untyped initial) { (untyped) -> untyped } -> Enumerator[untyped, untyped]",
Enumerator, :produce, 1
)
end

def test_product
assert_send_type(
"(Array[String], Array[Integer]) -> Enumerator::Product[String | Integer]",
Expand Down

0 comments on commit f3acb2a

Please sign in to comment.