Making all Traversables an Iterator or IteratorAggregate
| From: | Nikita Popov | Date: | Wed, 11 Mar 2020 09:50:22 +0000 |
| Subject: | Making all Traversables an Iterator or IteratorAggregate | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-108970@lists.php.net to get a copy of this message | ||
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.
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.
Regards,
Nikita