yield
(generator)

About me
- I'm Tien
- I'm a PHP/Drupal developer
- I'm working at GO1
Outline
- What is yield/generator?
- Demo
	- Simple usage
- Generator as object
- Saving memory
- Returning keys
- Pseudo keys
- Pass data to generator
 
- Why generator?
- How it work?
- When to use generator?
Do you know generator?
- return (80%)
- interator (20%)
What is generator?
- Is a Iterator.
- Return once item in array at a time.
- Look like a function, but behave like an iterator.
Iterator Interface
Iterator extends Traversable {
    /* Methods */
    abstract public mixed current ( void )
    abstract public scalar key ( void )
    abstract public void next ( void )
    abstract public void rewind ( void )
    abstract public boolean valid ( void )
}How iterator work?
$it->rewind();
while ($it->valid())
{
    $key = $it->key();
    $value = $it->current();
    // ...
    $it->next();
}Simple usage
function get_primes() {
    yield 2;
    $number = 3;
    while (true) {
        $prime = true;
        for ($i = 2; $i <= ($number / 2); $i++) {
            if (($number % $i) == 0) {
                $prime = false;
                break;
            }
        }
        if ($prime) {
            yield $number;
        }
        $number++;
    }
}
foreach (get_primes() as $number) {
    if ($number % 2 == 0) {
        print $number;
        break;
    }
}Saving memory demo
// Test 1
$m = memory_get_peak_usage();
foreach (line_one_by_one('file1.txt') as $l);
echo memory_get_peak_usage() - $m, "\n"; //Outputs 7248
// Test 2
$m = memory_get_peak_usage();
foreach (all_lines('file1.txt') as $l);
echo memory_get_peak_usage() - $m, "\n"; // Outputs 25668Pseudo keys
- Just like array keys, but
	- Can be any PHP datatype
- Can be duplicated
 
Peusedo keys
function get_items() {
    yield array('a' => 2) => 3;
    yield 'string' => 4;
    yield 1.234 => 5;
    yield function () {print 'hello';} => 6;
}
foreach (get_items() as $key => $value) {
    if (is_callable($key)) {
        call_user_func($key);
    }
    else if (is_array($key)) {
        print_r($key);
    }
    else {
        print $key;
    }
    print "=>";
    print $value . "\n";
}Pass data to generator
$logFileName = __DIR__ . '/error.log';
function logger($logFileName) {
  $f = fopen($logFileName, 'a');
  while ($logentry = yield) {
    fwrite($f, (new DateTime())->format('Y-m-d H:i:s ') . $logentry . PHP_EOL);
  }
}
$logger = logger($logFileName);
for ($i = 0; $i < 12; ++$i) {
  $logger->send('Message #' . $i);
}Generator as object
function xrange($min, $max)  {
    for ($i = $min; $i <= $max; $i++) {
        yield $i;
    }
}
$generator = xrange(0, 10);
while($generator->isValid()) {
    echo $generator->key() . ' => ' . $generator->current() . ', ';
    $generator->next();
}
// Print 0 => 0, 1 => 1 ...Notes
- Can not return values inside generator
- Use 'return;' to terminate generator
Why generator?
- Reduce memory use
- Faster than iterating over an array
- Cleaner and shorter code
- Allows to start processing the first few values immediately
How it work?

When to use generator?
- Process large array
- Save memory
- Write clean code
References
- Documentation
- Wiki
- Nice presentation about generators
- Practical usage
yield
By Tiến Võ Xuân
yield
- 1,109
 
   
   
  