> -----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 &current().

Jared






-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to