Bug #80917 [Com]: LimitIterator does not end at count
| From: | rowan dot collins at gmail dot com | Date: | Tue, 30 Mar 2021 10:18:57 +0000 |
| Subject: | Bug #80917 [Com]: LimitIterator does not end at count | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-233060@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=80917&edit=1
ID: 80917
Comment by: rowan dot collins at gmail dot com
Reported by: alexandreparent_dev at outlook dot com
Summary: LimitIterator does not end at count
Status: Open
Type: Bug
Package: SPL related
Operating System: All
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
A possibly clearer demonstration of what's happening, using an explicit Iterator rather than a
Generator: https://3v4l.org/IrAWU
Until the limit is reached, each call to next() on the LimitIterator calls next(), valid(),
current(), and key() on the wrapped iterator, in that order. After the limit is reached, it
continues to call next(), but none of the other methods.
In a foreach loop, this results in exactly one extra call to next(), but it actually passes through
*every* call to next(), unconditionally.
Previous Comments:
------------------------------------------------------------------------
[2021-03-29 20:36:54] levim@php.net
Actually, I agree with you; this _is_ a bug!
It should check the limit before iterating to the next value.
------------------------------------------------------------------------
[2021-03-29 20:19:46] levim@php.net
I'm pretty sure the test code is wrong based on your expectations; you are incrementing $count
and then checking if the count is greater than 2:
yield 0;
if (1 > 2) // false
yield 1;
if (2 > 2) // false
yield 2;
if (3 > 2) // true, but your limit is 3, meaning that you asked for this!
You need to reduce the limit to 2, or increase the comparison to
$count > 3.
------------------------------------------------------------------------
[2021-03-29 20:11:29] alexandreparent_dev at outlook dot com
I inverted actual and expected results.
------------------------------------------------------------------------
[2021-03-29 20:08:53] alexandreparent_dev at outlook dot com
Description:
------------
LimitIterator will try to iterate beyond $count. If its inner iterator never yield another item nor
return, the LimitIterator will not limit at the expected count.
Test script:
---------------
<?php
function generator(): iterable {
$count = 0;
while (true) {
yield $count++;
echo 'Yielded: ', $count - 1, \PHP_EOL;
if ($count > 2) {
while(true);
}
}
}
foreach (new \LimitIterator($generator(), 0, 3) as $count) {
echo 'Iterating: ', $count, \PHP_EOL;
}
Expected result:
----------------
Iterating: 0
Yielded: 0
Iterating: 1
Yielded: 1
Iterating: 2
Yielded: 2
// Hanging here
Actual result:
--------------
Iterating: 0
Yielded: 0
Iterating: 1
Yielded: 1
Iterating: 2
// Exiting here
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=80917&edit=1