Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:69433 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 92503 invoked from network); 1 Oct 2013 11:49:25 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Oct 2013 11:49:25 -0000 X-Host-Fingerprint: 80.4.21.210 cpc22-asfd3-2-0-cust209.1-2.cable.virginmedia.com Received: from [80.4.21.210] ([80.4.21.210:19964] helo=localhost.localdomain) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 5B/C1-17232-3C6BA425 for ; Tue, 01 Oct 2013 07:49:23 -0400 To: internals@lists.php.net,Ferenc Kovacs Message-ID: <524AB6BF.8030808@php.net> Date: Tue, 01 Oct 2013 12:49:19 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 MIME-Version: 1.0 References: <5D.40.07863.EB798425@pb1.pair.com> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Posted-By: 80.4.21.210 Subject: Re: [PHP-DEV] RFC: Draft: Nested Classes From: krakjoe@php.net (Joe Watkins) On 10/01/2013 12:16 PM, Ferenc Kovacs wrote: > On Sun, Sep 29, 2013 at 11:12 PM, Joe Watkins > wrote: > >> Hi All, >> >> I'd like to RFC on Nested Classes (Draft): >> >> 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 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