Reputation: 212452
I'm creating a class that uses a generator to return values when a particular method is called, something like:
class test {
protected $generator;
private function getValueGenerator() {
yield from [1,1,2,3,5,8,13,21];
}
public function __construct() {
$this->generator = $this->getValueGenerator();
}
public function getValue() {
while($this->generator->valid()) {
$latitude = $this->generator->current();
$this->generator->next();
return $latitude;
}
throw new RangeException('End of line');
}
}
$line = new test();
try {
for($i = 0; $i < 10; ++$i) {
echo $line->getValue();
echo PHP_EOL;
}
} catch (Exception $e) {
echo $e->getMessage();
}
Which works perfectly well when the generator is defined as a method within the class itself.... but I want to make this more dynamic, and use a closure as the generator, something like:
class test {
public function __construct() {
$this->generator = function() {
yield from [1,1,2,3,5,8,13,21];
};
}
}
Unfortunately, when I try to run this, I get
Fatal error: Uncaught Error: Call to undefined method Closure::valid()
in the call to getValue()
Can anybody explain the actual logic of why I can't call the generator this way? And how I might be able to use a closure rather than a hard-coded generator function?
Upvotes: 3
Views: 1523
Reputation: 18858
In the first example you invoke the method, creating the generator:
$this->generator = $this->getValueGenerator();
In the second you do not invoke it, so it's merely a closure:
$this->generator = function() {
yield from [1,1,2,3,5,8,13,21];
};
Invoking that closure should create the generator (PHP 7 if you don't want to assign an intermediate variable):
$this->generator = (function() {
yield from [1,1,2,3,5,8,13,21];
})();
Upvotes: 10