According to the documentation it if possible to delegate generation from any Traversable object. However I see the difference between yield from {a Generator instance} and yield from {an Iterator instance}.
An example.
This piece of code has an Iterator and a Generator that are doing the same: they provide the "1, 2, 3" sequence:
$iterator = new class implements \Iterator {
private $values = [1, 2, 3];
public function current()
{
return current($this->values);
}
public function next()
{
next($this->values);
}
public function key()
{
return key(this->values);
}
public function valid()
{
return current($this->values) !== false;
}
public function rewind()
{
reset($this->values);
}
};
$generator = (function ()
{
yield 1;
yield 2;
yield 3;
})();
But when I try to yield from them, I've got different results. Let's play with this function:
function skipOne(\Iterator $iterator)
{
$iterator->next();
yield from $iterator;
}
With a generator everything works as expected:
foreach (skipOne($generator) as $value) {
var_dump($value);
}
Output:
int(2)
int(3)
But with an Iterator it doesn't skip the first number:
foreach (skipOne($iterator) as $value) {
var_dump($value);
}
Output:
int(1)
int(2)
int(3)
I've found that yield from operator cause $iterator->rewind() invocation by some reason. What I'm doing wrong?