LeTigre
LeTigre

Reputation: 460

How to reset yield from within a generator in PHP

I am trying to setting up a coupled yield function. But when the function is called the second time, the integrated yield from is not reset.

I think the simplest way is to show using an example:

Code Example

PHP

class GeneratorTest
{

    public function generatorA() {
        for ($i = 0; $i < 10; $i++) {
            yield $i;
        }
    }


    // Generators can yield from other generators
    public function generatorB() {
        yield from $this->generatorA();  // << why is this not reset?

        for($i = 0; $i < 26; $i++) {
            yield chr(65 + $i);
        }
    }

}


$gen = new GeneratorTest();

echo "Test 1 from Generator B<br>";
foreach ($gen->generatorB() as $item) {
    echo $item . "<br>";
}

echo "Test 2 from Generator B<br>";
print_r(iterator_to_array($gen->generatorB()));

Expected?

I expected the output of "Test 2" to be identical to "Test 1". But actually it seems that the yield from generator is not reset when used.

Edit / Important:

Like noted by @Ganesh Wagh: Calling the generator in a second "for-each" works perfectly. The problem really only occurs, when calling "iterator_to_array"! Is this the expected behavior.

I tried to reset generatorA at the end of generatorB like this:

PHP

public function generatorB() {
    yield from $this->generatorA();

    for($i = 0; $i < 26; $i++) {
        yield chr(65 + $i);
    }
    $this->generatorA()->reset();
}

But to no avail.

Question: Is this the expected behavior? What do I have to do to reset the "inner" generator?

Upvotes: 1

Views: 1692

Answers (1)

LeTigre
LeTigre

Reputation: 460

All credit goes to @Frankich! (Second comment)

The problem was, that "iterator_to_array" evaluated the keys of the generator.

So a generator silently returns the keys of the used generator (yield from):

echo "Test 1 from Generator B\n";
foreach ($gen->generatorB() as $key => $item) {
    echo $key . '=>' .  $item . "\n";
}

Results in:

1=>1
2=>2
...
0=>A
1=>B
2=>C
...

So the keys in: iterator_to_array($gen->generatorB())) where overwritten (like pointed out by @Frankich)!

and only: iterator_to_array($gen->generatorB()), false) prevented that.

Thx for the input!

Upvotes: 1

Related Questions