php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67821 Generator can be rewound
Submitted: 2014-08-11 10:34 UTC Modified: 2014-08-11 10:51 UTC
From: thekid@php.net Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.5.15 OS: Any
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: thekid@php.net
New email:
PHP Version: OS:

 

 [2014-08-11 10:34 UTC] thekid@php.net
Description:
------------
A generator can be rewound if and only if its first yielded value has been fetched. As soon as we fetch the second (or any further) yielded value and *then* try to rewind it we actually get the exception. This is inconsistent.

Test script:
---------------
$f= function() { yield 1; yield 2; yield 3; };
$gen= $f();

foreach ($gen as $val) { var_dump($val); }
foreach ($gen as $val) { var_dump($val); }  // Exception("Cannot rewind a generator that was already run")

# Here's the bug:
foreach ($gen as $val) { var_dump($val); break; }
foreach ($gen as $val) { var_dump($val); }  // No exception

Expected result:
----------------
int(1)
Exception("Cannot rewind a generator that was already run")


Actual result:
--------------
int(1)
int(1)
int(2)
int(3)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-08-11 10:51 UTC] thekid@php.net
-Status: Open +Status: Not a bug
 [2014-08-11 10:51 UTC] thekid@php.net
Hrm, I just see that `Zend/tests/generators/generator_rewind.phpt` states:

"A generator can only be rewinded before or at the first yield"

(see also https://wiki.php.net/rfc/generators#rewinding_a_generator)

Again, this does seem inconsistent with the statement "generators will not support rewinding".
 [2014-08-11 18:37 UTC] nikic@php.net
rewind() is possible at first yield to support the standard Iterator pattern:

    for ($it->rewind(); $it->valid(); $it->next()) {
        // ...
    }

In which case the rewind is a no-op, priming notwithstanding.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Jul 09 11:01:34 2025 UTC