rfc:generators
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:generators [2012/09/01 15:56] – Close vote, RFC is accepted nikic | rfc:generators [2017/09/22 13:28] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 2: | Line 2: | ||
* Date: 2012-06-05 | * Date: 2012-06-05 | ||
* Author: Nikita Popov < | * Author: Nikita Popov < | ||
- | * Status: | + | * Status: |
===== Introduction ===== | ===== Introduction ===== | ||
Line 189: | Line 189: | ||
| | ||
mixed send(mixed $value); | mixed send(mixed $value); | ||
+ | mixed throw(Exception $exception); | ||
} | } | ||
</ | </ | ||
Line 228: | Line 229: | ||
* '' | * '' | ||
* '' | * '' | ||
+ | * '' | ||
==== Yield syntax ==== | ==== Yield syntax ==== | ||
Line 392: | Line 394: | ||
$logger-> | $logger-> | ||
$logger-> | $logger-> | ||
+ | </ | ||
+ | |||
+ | ==== Throwing into the generator ==== | ||
+ | |||
+ | Exceptions can be thrown into the generator using the '' | ||
+ | context and then resume the generator. It is roughly equivalent to replacing the current '' | ||
+ | resuming then. If the generator is already closed the exception will be thrown in the callers context instead (which is equivalent to replacing | ||
+ | the '' | ||
+ | other exception is thrown). | ||
+ | |||
+ | An example of the functionality: | ||
+ | |||
+ | <code php> | ||
+ | function gen() { | ||
+ | echo " | ||
+ | try { | ||
+ | yield; | ||
+ | } catch (Exception $e) { | ||
+ | echo " | ||
+ | } | ||
+ | echo " | ||
+ | } | ||
+ | |||
+ | $gen = gen(); | ||
+ | $gen-> | ||
+ | $gen-> | ||
+ | // and " | ||
</ | </ | ||
Line 430: | Line 459: | ||
==== Cloning a generator ==== | ==== Cloning a generator ==== | ||
- | Generators | + | Generators |
- | used to create a '' | + | |
- | + | ||
- | <code php> | + | |
- | class RewindableGenerator implements Iterator { | + | |
- | protected $original; | + | |
- | protected $current; | + | |
- | + | ||
- | public function __construct(Generator $generator) { | + | |
- | $this-> | + | |
- | $this-> | + | |
- | } | + | |
- | + | ||
- | public function rewind() { | + | |
- | if ($this-> | + | |
- | $this-> | + | |
- | $this-> | + | |
- | } | + | |
- | + | ||
- | public function valid() { | + | |
- | if (!$this-> | + | |
- | return $this-> | + | |
- | } | + | |
- | + | ||
- | public function current() { | + | |
- | if (!$this-> | + | |
- | return $this-> | + | |
- | } | + | |
- | + | ||
- | public function key() { | + | |
- | if (!$this-> | + | |
- | return $this-> | + | |
- | } | + | |
- | + | ||
- | public function next() { | + | |
- | if (!$this-> | + | |
- | $this-> | + | |
- | } | + | |
- | + | ||
- | public function send($value) { | + | |
- | if (!$this-> | + | |
- | return $this-> | + | |
- | } | + | |
- | + | ||
- | public function close() { | + | |
- | $this-> | + | |
- | if ($this-> | + | |
- | $this-> | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | function rewindable(Generator $generator) { | + | |
- | return new RewindableGenerator($generator); | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | It can be then used as follows: | + | |
- | + | ||
- | <code php> | + | |
- | function xrange($start, | + | |
- | for ($i = $start; $i <= $end; $i += $step) { | + | |
- | yield $i; | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | $range = rewindable(xrange(0, | + | |
- | foreach ($range as $i) { | + | |
- | echo $i, " | + | |
- | } | + | |
- | foreach ($range as $i) { | + | |
- | echo $i, " | + | |
- | } | + | |
- | </ | + | |
- | This will correctly output | + | Support for cloning was included in the initial version, but removed in PHP 5.5 Beta 3 due to implementational difficulties, |
==== Closing a generator ==== | ==== Closing a generator ==== |
rfc/generators.1346514961.txt.gz · Last modified: 2017/09/22 13:28 (external edit)