Bug #19632
openDisable external iterator for frozen enumerator
Description
Currently, methods to manipulate an external iterator like #next
and #feed
can be called even if a receiver of an enumerator is frozen. However, these methods change the state of an external iterator in an enumerator. Therefore, it seems a BUG to me, and these methods should raise FrozenError if the receiver is frozen.
e = 3.times.freeze
# Current
e.next # => 1
e.next # => 2
# Expected
e.next # raise FrozenError
Two years ago, this issue was mentioned in a comment.
I suggest fixing the following methods to raise FrozenError against a frozen enumerator.
Enumerator#next
Enumerator#next_values
Enumerator#peek
Enumerator#peek_values
Enumerator#feed
Enumerator#rewind
Also, even if an enumerator is frozen, it does not affect other methods for internal iterators.
Updated by make_now_just (Hiroya Fujinami) about 1 month ago
A Pull Request for this is created. https://github.com/ruby/ruby/pull/7791
Updated by nobu (Nobuyoshi Nakada) about 1 month ago
Sounds reasonable.
Updated by matz (Yukihiro Matsumoto) 27 days ago
peek
does not seem to modify the enumerator? Should we prohibit it (or not)?
Updated by make_now_just (Hiroya Fujinami) 27 days ago
If a result value is not stored, peek
invokes the iterator and stores it in its internal state. For that reason, I consider peek
is also a mutable method like next
.
If you call peek
in advance and then call freeze
, peek
will not change the internal state. IMHO, this case is exceptional and should still raise a FrozenError
for simplicity. However, I would follow matz's decision.
Updated by Eregon (Benoit Daloze) 27 days ago
+1. And yes peek can have side effect so should be considered mutating method.