(Sorry, I pressed something that sent the message prematurely)

On Thu, 7 Jun 2012 01:10:52 +0200, Nikita Popov wrote:

current() and key() should return false when !valid()

Are you sure about that? The Iterator::current() docs don't specify
anything, but the Iterator::key() docs say that it should return NULL
on failure. Checking on the first spl class that came to my mind
SplFixedArray also returns NULL when it is out of elements.

My bad. I was under the impression the semantics were similar to those of next(), key(), etc. Instead the docs say under current() that the function can return anything, under key) that it returns NULL on failure (and issues an E_NOTICE) and for next() that "the return value is ignored" -- whatever that means; I'll interpret it as saying anything can be returned. I'm not sure how correct this documentation is, though.

next() is underspecified.
Not sure what exactly you mean. next() really doesn't do much more
than resuming the generator. What should I add additionally about it?

Sorry for not having been clearer. I mean you say "Resumes the generator (unless the generator is already closed)", but you don't specify what it returns (though apparently Iterator does not require you to specify anything specific) and you don't say what happens when theiterator is already closed.

In fact, if you can't implement Iterator in full, you should implement Traversable instead.
Not sure whether the lack of rewinding behavior really disqualifies it
to use the Iterator interface. I think having the internal iteration
methods exposed is quite handy, especially if you consider their use
as coroutines, where you often want to call the iteration interface
manually and not using a foreach loop.


Well, the Iterator::rewind() docs say that rewind() rewinds the iterator. If this is not possible, then Iterator should not be implemented. See http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.8

In the same order, your options are:

1. As changing Iterator is not possible, have a new interface, say, BasicIterator from which Iterator will inherit without rewind(). 2. Make all the Generators rewindable (possibly by fetching a new generator each time).
3. Do not implement Iterator.

(By the way, if you implement Traversable, one you can always use the unsafe IteratorIterator to get access to the methods)

 * Exceptions can be thrown from generators as always.
 * Not sure what you mean by "generator returns function". What would
be that problem with that?

I mean how do you deal with "return $foo" in the body of the generator? Does it work like a final yield? Is the return value ignored?

 * Generators can be methods, as shown in the example in the
Introduction section. Closures can also be generators.

Can other callable classes be generators?

Are you planning on any internal API for functions to implement generators (though I really haven't thought how that would work)?

--
Gustavo Lopes

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

Reply via email to