Project

General

Profile

Actions

Bug #19632

open

Disable external iterator for frozen enumerator

Added by make_now_just (Hiroya Fujinami) about 1 month ago. Updated 27 days ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:113420]

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 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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0