Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can PHP generators be cloned?

In the PHP documentation it says that:

This flexibility does come at a cost, however: generators are forward-only iterators, and cannot be rewound once iteration has started. This also means that the same generator can't be iterated over multiple times: the generator will need to either be rebuilt by calling the generator function again, or cloned via the clone keyword. Documentation

However I tried writing a code that clones the generator object that I received from a method and I got an error specifying that a generator object cant be cloned:

class Course {
    private $students = array("avi" , "haim" , "maor" , "liran" , "yossi");

    function generateStudents() {
        foreach ($this->students as $student) {
            yield $student;
        }
    }
}

$ob = new Course();
$generator = $ob->generateStudents();

// Fatal error: Trying to clone an uncloneable object of class Generator
$generator2 = clone $generator;

?>
like image 650
user3021621 Avatar asked Apr 04 '14 09:04

user3021621


People also ask

How do PHP generators work?

The generator function opens a file and then yields each line of the file as and when it is required. Each time the generator is called, it continues from where it left off. It doesn't start from the beginning again as its state had been saved when the yield statement was executed.

What is a PHP generator?

A generator in PHP is a function that allows us to iterate over data without needing to build an array in memory. Unlike a standard function, which can return only a single value, a generator can yield as many values as it needs to.


1 Answers

According to the RFC, generators cannot be cloned:

Generators cannot be cloned.

Support for cloning was included in the initial version, but removed in PHP 5.5 Beta 3 due to implementational difficulties, unclear semantics and no particularly convincing use cases.

It looks like the documentation reflects the initial version, and needs updating. There is a documentation bug raised to address this.

Also in the RFC, it refers to reasons why you might not want to reuse a generator:

Rewinding to some degree goes against the concept of generators, as they are mainly intended as one-time data sources that are not supposed to be iterated another time. On the other hand, most generators probably are rewindable and it might make sense to allow it. One could argue though that rewinding a generator is really bad practice (especially if the generator is doing some expensive calculation). Allowing it to rewind would look like it is a cheap operation, just like with arrays.

like image 181
cmbuckley Avatar answered Oct 05 '22 22:10

cmbuckley