A generator delegating to another with yield from

Composing generators by looping and re-yielding works and loses the inner generator’s keys and its return value, which is usually discovered much later.

function lines(array $files) {
    foreach ($files as $file) {
        yield from readLines($file);      // keys come from the inner one
    }
}

// which is why this loses records:
count(iterator_to_array(lines($files)));         // keys collide
count(iterator_to_array(lines($files), false));  // all of them

Keys from the inner generator are passed through, and a generator that yields without a key restarts its counter — so composing two of them produces colliding integer keys and iterator_to_array keeps only the last value for each. Passing false as the second argument reindexes and keeps everything. yield from also propagates the inner generator’s return value to getReturn(), which the manual loop cannot do at all.