1

I am programming a generic component which wraps a generator and does routine manipulation:

  • filter by key
  • transform the value
  • etc.

To emulate the wrapped generator as close as possible, I want to use references if the generator is using references.

When I try to iterate a non-reference generator using foreach ($generator as $key => &$value) methodology, I receive the following error:

You can only iterate a generator by-reference if it declared that it yields by-reference

Is there a way to find out, if the generator at hand is returning references? I did not have success using reflection:

$reflectedGeneratorValueSupplier = new \ReflectionMethod($generator, 'current');
$this->canReference = $reflectedGeneratorValueSupplier->returnsReference(); //always false

Also, iterating generator without using foreach construct does not work at all with references:

while ($generator->valid()) {
    $key = $generator->key();
    $value =& $generator->current(); //error, only variables can be passed by reference
    
    $generator->next();
}
  • See this - https://stackoverflow.com/a/54769856/296555 – waterloomatt Aug 20 '20 at 16:05
  • Excuse me, I don't understand how that relates to the question at hand. I need to find out *if* a generator can be yielded by reference, not *to construct* a generator which yields references. – informatik-handwerk.de Aug 20 '20 at 16:21
  • What is `IhdeReflection`? Is this a custom reflection library? Maybe it has a bug in the function shown? – IMSoP Aug 20 '20 at 17:40
  • No that is not it, just see it as a piece of preudocode. `$generator->current()` is simply a method which does not return by reference. no matter how you define a generator function. – informatik-handwerk.de Aug 20 '20 at 20:48
  • @informatik-handwerk.de I'm confused; you said "I did not have success using reflection" and showed us some reflection code, but now you say that is "pseudo-code". What is the code you actually tried? Please [edit] the question to include a [mcve], so that we're not forced to guess what you're actually doing. – IMSoP Aug 21 '20 at 13:11
  • First of all: Thank so much you for the eye opener!! Second, the accepted answer indeed revealed that there was the problem - I was not aware, that there was a \ReflectionGenerator API in PHP and attempted to use \ReflectionMethod... – informatik-handwerk.de Aug 22 '20 at 18:15

1 Answers1

0

Using ReflectionGenerator and then getFunction seems to work.

http://sandbox.onlinephpfunctions.com/code/92ed79dc7a6e925243f0c55898a5d1170f994189

<?php

function &generate(&$arr)
{
    foreach ($arr as $key => &$value) {
        yield $key => $value;
    }
};

$input = range(0,100);
$generator = generate($input);

$r = new ReflectionGenerator ($generator);

var_dump($r->getFunction()->returnsReference()); // true
waterloomatt
  • 3,662
  • 1
  • 19
  • 25