Skip to content

Commit 5bbb9c3

Browse files
Improve docs for Iterator step-by-step iteration (#13967)
1 parent 4001a79 commit 5bbb9c3

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/iterator.cr

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,46 @@ require "./enumerable"
3939
# iter.size # => 0
4040
# ```
4141
#
42+
# ### Iterating step-by-step
43+
#
44+
# An iterator returns its next element on the method `#next`.
45+
# Its return type is a union of the iterator's element type and the `Stop` type:
46+
# `T | Iterator::Stop`.
47+
# The stop type is a sentinel value which indicates that the iterator has
48+
# reached its end. It usually needs to be handled and filtered out in order to
49+
# use the element value for anything useful.
50+
# Unlike `Nil` it's not an implicitly falsey type.
51+
#
52+
# ```
53+
# iter = (1..5).each
54+
#
55+
# # Unfiltered elements contain `Iterator::Stop` type
56+
# iter.next + iter.next # Error: expected argument #1 to 'Int32#+' to be Int32, not (Int32 | Iterator::Stop)
57+
#
58+
# # Type filtering eliminates the stop type
59+
# a = iter.next
60+
# b = iter.next
61+
# unless a.is_a?(Iterator::Stop) || b.is_a?(Iterator::Stop)
62+
# a + b # => 3
63+
# end
64+
# ```
65+
#
66+
# `Iterator::Stop` is only present in the return type of `#next`. All other
67+
# methods remove it from their return types.
68+
#
69+
# Iterators can be used to build a loop.
70+
#
71+
# ```
72+
# iter = (1..5).each
73+
# sum = 0
74+
# while !(elem = iter.next).is_a?(Iterator::Stop)
75+
# sum += elem
76+
# end
77+
# sum # => 15
78+
# ```
79+
#
80+
# ### Implementing an Iterator
81+
#
4282
# To implement an `Iterator` you need to define a `next` method that must return the next
4383
# element in the sequence or `Iterator::Stop::INSTANCE`, which signals the end of the sequence
4484
# (you can invoke `stop` inside an iterator as a shortcut).

0 commit comments

Comments
 (0)