> -----Original Message----- > From: Hannes Magnusson [mailto:hannes.magnus...@gmail.com] > Sent: 29 August 2012 22:50 > To: Derick Rethans > Cc: Nikita Popov; Jared Williams; PHP internals > Subject: Re: [PHP-DEV] [VOTE] Generators > > On Wed, Aug 29, 2012 at 10:19 PM, Derick Rethans > <der...@php.net> wrote: > > On Wed, 29 Aug 2012, Nikita Popov wrote: > > > >> On Wed, Aug 29, 2012 at 10:10 PM, Derick Rethans > <der...@php.net> wrote: > >> > On Wed, 29 Aug 2012, Nikita Popov wrote: > >> > > >> >> > function &bind(array $keys, array &$row) { > >> >> > foreach($keys as $key) > >> >> > yield $key => $row[$key]; } > >> >> > > >> >> > $row = []; > >> >> > $it = bind(['a', 'b'], $row); > >> >> > > >> >> > foreach($it as $key => &$ref) > >> >> > echo $key; > >> >> > echo "\n"; > >> >> > foreach($it as $key => &$ref) > >> >> > echo $key; > >> >> > >> >> Thanks, this is now fixed. It'll throw an exception now, saying > >> >> that you can't traverse an already closed generator. > >> > > >> > Nothing in the core throws an exception, why would this?! > >> > >> To my knowledge all iterator-related functionality is supposed to
> >> throw exceptions (as it is a feature related to the object > oriented > >> part of PHP). At leas this is what a quick search of the code base > >> gave me. (See > >> http://lxr.php.net/xref/PHP_TRUNK/ext/spl/spl_dllist.c#1248 > >> for example). > > > > "ext/spl" - SPL is not *core* language. The generators are. Don't > > throw exceptions from core features! > > In general I agree with core language features shouldn't be > throwing exceptions... > But SPL definitely should never have been its own extension > and most of it should have been core language features - and > throwing exceptions in many of those cases makes perfect sense. > > We also have the case of IteratorAggregate throwing exception > (which is a *core* language feature, not defined in ext/spl): > > $ ./sapi/cli/php -r 'class foo implements IteratorAggregate { function > getIterator() { return new stdclass; } } foreach(new foo as $bar) {}' > > Fatal error: Uncaught exception 'Exception' with message > 'Objects returned by foo::getIterator() must be traversable > or implement interface Iterator' in Command line code:1 Stack trace: > #0 Command line code(1): unknown() > #1 {main} > thrown in Command line code on line 1 > Speaking of IteratorAggregates and spl. I think there should be some discussion about what can be done to get the spl iterators to handle references. For instance, you cannot use CachingIterator on a reference yielding generator. And think the only method you can get it to work, feels rather kludgy. class CachingGeneratorIterator implements IteratorAggregate { private $it; function __construct(Generator $it) { $this->it = $it; } function &getIterator() { $previousKey = null; foreach($this->it as $key => &$ref) { if ($previousKey !== null) yield $previousKey => $previousRef; $previousKey = $key; $previousRef = &$ref; } if ($previousKey !== null) yield $previousKey => $previousRef; } function hasNext() { return $this->it->valid(); } } Limitations are that you have to use foreach() rather than current() to retrieve yielded references, because you can't implement an iterator with a method signature of ¤t(). Jared -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php