Re: RFC: Draft: Nested Classes
| From: | Joe Watkins | Date: | Tue, 01 Oct 2013 11:49:19 +0000 |
| Subject: | Re: RFC: Draft: Nested Classes | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-69433@lists.php.net to get a copy of this message | ||
On 10/01/2013 12:16 PM, Ferenc Kovacs wrote:
On Sun, Sep 29, 2013 at 11:12 PM, Joe Watkins <krakjoe@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
HI Tyrael,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.phpHi 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?
1) Reflection will have the same kind of access to nested classes asit does to normal classes
2) Same goes for serialization, these are normal classes declared inthe 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 supportwe 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 enforcethese 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 classnames 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; theversion 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 overwhat 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