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/08/25 16:25] – [Request for Comments: Generators] fixed ajf | 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 222: | Line 223: | ||
Apart from the above the '' | Apart from the above the '' | ||
- | * '' | + | * '' |
* '' | * '' | ||
* '' | * '' | ||
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> | + | Support |
- | 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, | + | |
- | | + | |
- | yield $i; | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | $range = rewindable(xrange(0, 5)); | + | |
- | foreach ($range as $i) { | + | |
- | echo $i, " | + | |
- | } | + | |
- | foreach ($range as $i) { | + | |
- | echo $i, " | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | This will correctly output the 0..5 range twice. | + | |
==== Closing a generator ==== | ==== Closing a generator ==== | ||
Line 538: | Line 494: | ||
This is a list of generators-related error conditions: | This is a list of generators-related error conditions: | ||
- | * Manual construction of '' | ||
- | * Closing a generator while it is running: '' | ||
- | * Yielding a key that isn't an integer or a key: '' | ||
- | * Trying to iterate a non-ref generator by-ref: '' | ||
* Using '' | * Using '' | ||
* Using '' | * Using '' | ||
+ | * Manual construction of '' | ||
+ | * Yielding a key that isn't an integer or a key: '' | ||
+ | * Trying to iterate a non-ref generator by-ref: '' | ||
+ | * Trying to traverse an already closed generator: '' | ||
+ | * Trying to rewind a generator after the first yield: '' | ||
* Yielding a temp/const value by-ref: '' | * Yielding a temp/const value by-ref: '' | ||
* Yielding a string offset by-ref: '' | * Yielding a string offset by-ref: '' | ||
Line 665: | Line 622: | ||
The current implementation can be found in this branch: https:// | The current implementation can be found in this branch: https:// | ||
+ | |||
+ | I also created a PR so that the diff can be viewed more easily: https:// | ||
===== Vote ===== | ===== Vote ===== | ||
- | <doodle title=" | + | <doodle title=" |
* Yes | * Yes | ||
* No | * No |
rfc/generators.1345911944.txt.gz · Last modified: 2017/09/22 13:28 (external edit)