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 638717a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
36 changes: 36 additions & 0 deletions core/enumerator.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,42 @@
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 prev) -> untyped } -> Producer[untyped]

# <!--
# 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(
"(Integer initial) { (Integer) -> Integer } -> Enumerator[Integer, untyped]",
Enumerator, :produce, 1, &:succ
)
end

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

0 comments on commit 638717a

Please sign in to comment.