Bug #80010 [Opn->Nab]: No error notification or throw when returning iterator from iterator method

From: Date: Sun, 23 Aug 2020 21:17:10 +0000
Subject: Bug #80010 [Opn->Nab]: No error notification or throw when returning iterator from iterator method
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-228721@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80010&edit=1

 ID:                 80010
 Updated by:         requinix@php.net
 Reported by:        petr dot vejchoda at seznam dot cz
 Summary:            No error notification or throw when returning
                     iterator from iterator method
-Status:             Open
+Status:             Not a bug
 Type:               Bug
-Package:            *Compile Issues
+Package:            Class/Object related
 Operating System:   Win10
 PHP Version:        7.3.21
 Block user comment: N
 Private report:     N

 New Comment:

https://3v4l.org/bq2df

You didn't say it, but I assume what you're reporting is how the [4]=> output (the one
for $e) is an empty array.

    public function secondIterator(\Iterator $first): \Iterator
    {
        if ($this->whatever === true)
        {
            return $first;
        }

        foreach($first as $key=>$value)
        {
            yield $key => $value * $value;
        }
    }

Any function that contains a yield will always return a Generator. Always. Even if it returns before
it yields. The return value from a Generator function is kept separate from the yielded values.

https://www.php.net/manual/en/language.generators.syntax.php
https://www.php.net/manual/en/generator.getreturn.php

$e contains a Generator with no yielded items, and its getReturn() will give the passed iterator.

https://3v4l.org/bQJkN


Previous Comments:
------------------------------------------------------------------------
[2020-08-23 10:07:28] petr dot vejchoda at seznam dot cz

Description:
------------
When writing iterator method, complier lets me return Iterator variable, but it doesn't pass
it. I am actually at version 7.3.20 and I don't care to update. I read changelog.
Note value in $e in supplied code.

Test script:
---------------
class test
{
    private $whatever = false;

    public function __construct()
    {
        $a = iterator_to_array($this->firstIterator());
        $b = iterator_to_array($this->secondIterator($this->firstIterator()));
        $c = iterator_to_array($this->thirdIterator($this->firstIterator()));

        $this->whatever = true;
        $d = iterator_to_array($this->firstIterator());
        $e = iterator_to_array($this->secondIterator($this->firstIterator()));
        $f = iterator_to_array($this->thirdIterator($this->firstIterator()));

        var_dump([$a, $b, $c, $d, $e, $f]);
    }

    public function firstIterator(): \Iterator
    {
        yield 'a'=> 1;
        yield 'b'=> 2;
        yield 'c'=> 3;
    }

    public function secondIterator(\Iterator $first): \Iterator
    {
        if ($this->whatever === true)
        {
            return $first;
        }

        foreach($first as $key=>$value)
        {
            yield $key => $value * $value;
        }
    }

    public function thirdIterator(\Iterator $first): \Iterator
    {
        if ($this->whatever === true)
        {
            return $first;
        }

        return $this->thirdSubIterator($first);
    }

    public function thirdSubIterator(\Iterator $first): \Iterator
    {
        foreach($first as $key=>$value)
        {
            yield $key => $value * $value;
        }
    }
}

Expected result:
----------------
Returned Iterator should be either passed regularly or iterator method should not be accepted at all
as an iterator method, throwing exception



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=80010&edit=1


Thread (7 messages)

« previous php.bugs (#228721) next »