On Wed, Mar 11, 2020 at 10:50 AM Nikita Popov <nikita....@gmail.com> wrote:

> Hi internals,
>
> Userland classes that implement Traversable must do so either through
> Iterator or IteratorAggregate. The same requirement does not exist for
> internal classes: They can implement the internal get_iterator mechanism,
> without exposing either the Iterator or IteratorAggregate APIs. This makes
> them usable in get_iterator(), but incompatible with any Iterator based
> APIs.
>

This should have said: "This makes them usable in foreach(), but
incompatible with any Iterator based APIs."

A lot of internal classes do this, because exposing the userland APIs is
> simply a lot of work. I would like to add a general mechanism to make this
> simpler: https://github.com/php/php-src/pull/5216 adds a generic
> "InternalIterator" class, that essentially converts the internal
> get_iterator interface into a proper Iterator. Internal classes then only
> need to a) implement the IteratorAggregate interface and b) add a
> getIterator() method with an implementation looking like this:
>
> // WeakMap::getIterator(): Iterator
> ZEND_METHOD(WeakMap, getIterator)
> {
>     if (zend_parse_parameters_none() == FAILURE) {
>         return;
>     }
>     zend_create_internal_iterator_zval(return_value, ZEND_THIS);
> }
>
> This allows internal classes to trivially implement IteratorAggregate, and
> as such allows us to enforce that all Traversables implement Iterator or
> IteratorAggregate.
>

Does anyone have thoughts on this change? Mostly this is a feature for
extensions, but also user-visible in that a bunch of classes will switch
from being Traversable to being IteratorAggregate.

We may also want to convert some existing Iterators to IteratorAggregates.
For example SplFixedArray currently implements Iterator, which means that
it's not possible to have nested loops over SplFixedArray. We could now
easily fix this by switching it to use IteratorAggregate, which will allow
multiple parallel iterators to work on the same array. Of course, there is
BC break potential in such a change.

There's some bikeshed potential here regarding the class name. I picked
"InternalIterator" as an iterator for internal classes, but "internal
iteration" is also a technical term (the opposite of "external iteration"),
so maybe that name isn't ideal.

Regards,
Nikita

Reply via email to