Question

function yielding()
{
    for ($i = 0; $i < 10; $i++) {
        var_dump(yield);
    }
}

$y = yielding();

foreach ($y as $val) {
    $y->send('foo');
}

output:

string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"
NULL
string(3) "foo"

i expected the output to be: 10 time string(3) "foo", but instead the output is one NULL and one string(3) "foo" (9 times). why is it? does generator->send() skip one iteratoration?

Was it helpful?

Solution

yield is used for both sending and receiving values inside the generator. From the Generator RFC: If nothing was sent (e.g. during foreach iteration) null is returned.

So in your code, the generator is resumed twice:

  1. once for ($y as $val) -- yield returns null inside the generator
  2. once for $y->send('foo') -- yield returns 'foo' inside the generator

When I ran your code I got 10 lines of output, ending with NULL

string(3) "foo"
NULL
...
string(3) "foo"
NULL

OTHER TIPS

The function send() is used to inject values
If you want to print foo ten times then perhaps the following will work (Not tested)

function yielding()
{
    for ($i = 0; $i < 10; $i++) {
////get a value from the caller
        $string = yield;
        echo $string;
    }
}

Edit :

$y = yielding();

for($k=0;$k<10;$k++)
    $y->send('foo');

This will print it ten times.

What happens when you iterate over the object : (Quoting from the manual) "When you iterate over that object (for instance, via a foreach loop), PHP will call the generator function each time it needs a value, then saves the state of the generator when the generator yields a value so that it can be resumed when the next value is required.

Once there are no more values to be yielded, then the generator function can simply exit, and the calling code continues just as if an array has run out of values."

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top