On 10/01/2013 12:16 PM, Ferenc Kovacs wrote:
On Sun, Sep 29, 2013 at 11:12 PM, Joe Watkins <krak...@php.net>
wrote:
Hi All,
I'd like to RFC on Nested Classes (Draft):
https://wiki.php.net/rfc/**nested_classes<https://wiki.php.net/rfc/nested_classes>
There's been a little bit of discussion already about it, in the usual
places mostly, but also while considering anonymous classes on the
lists ... time to make it public I guess ...
Cheers Joe
-- PHP Internals - PHP Runtime Development Mailing List To
unsubscribe, visit: http://www.php.net/unsub.php
Hi Joe,
I really like the idea, as it is a recurring problem that you create
a library/package, what you want others to use, but there are some
parts of it, which you want to keep as a blackbox to your users, so
you can change it in the future, without breaking their code.
Currently if you want hard guarantees your only option is to keep
that kind of code in private functions, and if you put that into
logically separated classes, your only option is to use docblock
comments like the @api to hint that which parts are intended for
consumption, but sadly nobody really follows that. So I would really
like the idea of having classes which can only be accessed from that
specific component, but sadly we don't have real packages in php
with package level visibility as that could also solve this problem.
Having nested classes could be still really useful in this
scenario, so I'm +1 on this feature, but there are a couple of
questions I would like to see answered:
1. Would there be reflection support for this feature (currently you
can access private methods/properties through Reflection, I think it
would make sense to be able to do the same with the nested classes).
2. Would it be possible to serialize/unserialize a class
referencing an instance of a nested class without losing the
information it holds? 3. What happens when a nested class with the
same name is used in two separate class?
What do you think?
HI Tyrael,
1) Reflection will have the same kind of access to nested classes as
it does to normal classes
2) Same goes for serialization, these are normal classes declared in
the pseudo namespace of the declaring class
3) Because of how classes are named, this cannot reasonably occur
My thoughts have somewhat moved on from the version I have RFC'd.
Apparently the version I have RFC'd is too basic, we want more support.
https://github.com/krakjoe/php-src/compare/anon_class_objects...nesting_complex
The branch above is the work on a more complete support of the idea.
https://github.com/krakjoe/php-src/blob/2275e89c6c21c2866dd031915c37838cb31b68c0/Zend/tests/nested/100.phpt
<?php
class foo
{
:protected interface iface {
public function mthd();
}
:protected abstract class my implements foo\iface
{
public function mthd() {
return $this;
}
}
/* I'm private */
:private class baz
{
/* I'm very private */
:private class qux extends foo\my
{
public function __construct() {
$this->bar = new foo\bar();
}
}
/* I'm useful */
public function __construct() {
$this->qux = new foo\baz\qux();
}
}
/* I'm protected */
:protected class bar
{
public function __construct() {
}
}
public function __construct() {
$this->bar = new foo\bar();
$this->baz = new foo\baz();
}
}
var_dump(new foo());
?>
The above code, taken from the first test, shows the kind of support
we might have as an alternative to the simple version of nesting I RFC'd.
private: you cannot use outside of the super class
protected: you must share a scope in common with the class to use it
public: you can access the class from anywhere
There are a few problems with this, it's simple enough to enforce
these rules on ZEND_NEW ZEND_ADD_INTERFACE ZEND_ADD_TRAIT, however,
where ZEND_FETCH_CLASS is used things are a little more complex, we
don't have enough information, or don't pass it anyway to detect the
scope requesting the FETCH_CLASS, I'm sure this isn't an insurmountable
problem, but I'm sure that anything we do in ZEND_FETCH_CLASS is going
to be felt, a lot, so it had better be minimal ...
Note that the syntax above with the colons in front of the class
names are just circumventing a problem I've not been able to overcome in
the parser, I'm assured it's possible to do without it.
If we want any support at all, these are the options we have; the
version I RFC'd, where the scope of the class is implicit in the
location of the declaration, or we try to propagate support for the
access modifiers throughout the VM as in the second branch.
I think the latter is more appealing, gives much more control over
what is actually allowed and gives properly private classes, but I think
the first implementation has barely any impact on the things around it
and covers the most compelling use cases adequately.
Cheers
Joe
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php