On 2012-08-09 14:25, Larry Garfield wrote:
On 07/27/2012 07:23 AM, Lester Caine wrote:

Nikita - I am looking for a well reasoned argument as to why generator
has to be added at all! 'Just because it can be' is not a valid
argument, but perhaps you could add to the RFC the performance
implication or advantage of what is being proposed. That would at
least be some comparison with the current methods of doing the same
thing?


Anthony had a very good writeup on generators and how they compare to
iterators last week:

http://blog.ircmaxell.com/2012/07/what-generators-can-do-for-you.html

I think that does a good job of laying out the case for generators as
"low-effort iterators".

I for one am lazy, and would much prefer writing:
<?php
function append_iterator($first, $second)
{
    foreach($first as $i)
    {
        yield $i;
    }
    foreach($second as $i)
    {
        yield $i;
    }
}
?>

to

<?php
function append_iterator($first, $second)
{
    if(is_object($first) && !($first instanceof Iterator))
    {
        $first = (array)$first;
    }
    if(is_array($first))
    {
        $first = new ArrayIterator($first);
    }
    if(is_object($second) && !($second instanceof Iterator))
    {
        $second = (array)$second;
    }
    if(is_array($second))
    {
        $second = new ArrayIterator($second);
    }
    return new myAppendIterator($first, $second);
}

class myAppendIterator implements Iterator
{
        private $_state = 0;
        private $_key;
        private $_current;

        private $first, $second;

        public function __construct($first, $second)
        {
                $this->first = $first;
                $this->second = $second;
        }

        public function rewind()
        {
                $this->first->rewind();
                $this->second->rewind();
                $this->state = 0;
        }

        public function current()
        {
                return $this->_current;
        }

        public function key()
        {
                return $this->_key;
        }

        public function next()
        {
                switch($this->_state)
                {
                case -1:
                        return;
                case 0:
                        $this->first->rewind();
                        $this->_state = 1;
                case 1:
                        if($this->first->valid())
                        {
                                $this->_current = $this->first->current();
                                $this->_key = $this->first->key();
                                $this->first->next();
                                return;
                        }
                        else
                        {
                                $this->second->rewind();
                                $this->_state = 2;
                        }
                case 2:
                        if($this->second->valid())
                        {
                                $this->_current = $this->second->current();
                                $this->_key = $this->second->key();
                                $this->second->next();
                                return;
                        }
                        else
                        {
                                $this->_state = -1;
                                return;
                        }
                }
        }

        public function valid()
        {
                return $this->_state != -1;
        }
}
?>


One question, though: It looks based on the voting like finally {}
blocks are going in.  So... what should happen in the following situation:

function stuff() {
   try {
     foreach (range(1, 100) as $i) {
       yield $i;
     }
   }
   finally {
     print "All done";
   }
}

Does "All done" get printed once, or 101 times?  Similarly:

function things() {
   $i = 1;
   try {
     while (true) {
       yield $i++;
     }
   }
   finally {
     print "All done";
   }
}

That will run indefinitely.  So will "All done" ever print, or does that
finally become unreachable?

My own gut expectation (the answers that would surprise me the least) would be (a) once (because the foreach is _inside_ the try block, and the catch/finally handler is hence _outside_ the loop); and (b) the finally{} is unreachable (assuming that loop doesn't manage to throw an exception!) because control flow never gets to the end of the try block.


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

Reply via email to