Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:63410 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 66790 invoked from network); 15 Oct 2012 12:57:54 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 15 Oct 2012 12:57:54 -0000 Authentication-Results: pb1.pair.com header.from=cpriest@zerocue.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=cpriest@zerocue.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zerocue.com designates 74.115.204.51 as permitted sender) X-PHP-List-Original-Sender: cpriest@zerocue.com X-Host-Fingerprint: 74.115.204.51 relay-hub201.domainlocalhost.com Received: from [74.115.204.51] ([74.115.204.51:11643] helo=relay-hub201.domainlocalhost.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 58/14-42204-0580C705 for ; Mon, 15 Oct 2012 08:57:53 -0400 Received: from MBX202.domain.local ([169.254.169.44]) by HUB201.domain.local ([192.168.68.45]) with mapi id 14.02.0283.003; Mon, 15 Oct 2012 08:56:58 -0400 To: "Nikita Popov (nikita.ppv@gmail.com)" CC: "internals@lists.php.net" Thread-Topic: [PHP-DEV] [PHP-DEV [RFC] Property Accessors v1.2 : Backing Property Thread-Index: Ac2q0dIvJjjALu2RQmqw8Y98m8OyDw== Date: Mon, 15 Oct 2012 12:56:58 +0000 Message-ID: <9570D903A3BECE4092E924C2985CE485612B64C8@MBX202.domain.local> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [192.168.64.23] Content-Type: multipart/alternative; boundary="_000_9570D903A3BECE4092E924C2985CE485612B64C8MBX202domainloc_" MIME-Version: 1.0 Subject: [PHP-DEV] [PHP-DEV [RFC] Property Accessors v1.2 : Backing Property From: cpriest@zerocue.com (Clint Priest) --_000_9570D903A3BECE4092E924C2985CE485612B64C8MBX202domainloc_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable * I'm moving this into its own mail thread because talking about 3* differe= nt topics under the same chain is ridiculous (has anyone suggested forums i= nstead of email??) > So here comes my round of feedback on the current proposal. > > But before getting to that: I have collected a bit of data how getter and= setter are currently used in Symfony and ZF: > https://gist.github.com/3884203 Mainly so I get a better overview of the = situation, but might be of interest for other people involved > in this discussion too. > > So, my points on the proposal, in no particular order: > > 3. Protected backing property > ------------------------------------------ > > The RFC currently contains just a single code example, namely setting a $= Seconds property through an $Hours property, which is an > example where you want to override both accessors and there is a backing = property that already exists "naturally". > > If you on the other hand you consider cases where you only want to overri= de either the set or the get behavior and there doesn't > already exist a backing property, you will end up with a code like this: > > protected $_isEnabled; > public $isEnabled { > get() { return $this->_isEnabled; } > set($isEnabled) { $this->_isEnabled =3D (bool) $isEnabled; } > } > > The above code really only adds a bool cast, but still it has to do two t= hings: Add a protected backing property and define a getter > which basically matches the default behavior. With automatic properties a= s they are currently implemented you could write: > > > public $isEnabled { > get(); > set($isEnabled) { $this->__isEnabled =3D (bool) $isEnabled; } > } > > This is closer to what I actually want to do, but it relies on using $thi= s->__isEnabled, which is really just an implementation detail. > > Instead, I would rather want to have access to the "underlying" property: > > public $isEnabled { > get(); > set($isEnabled) { $this->isEnabled =3D (bool) $isEnabled; } > } > > I know that the wording is a bit vague; another way to put it, is that th= e above inverts the current shadowing behavior: > > In the current implementation, if there exists a "plain" property and an = "accessor" property with the same name, then the plain > property shadows the accessor property. As you say, this is to help lazy-= loading. I don't really buy the argument about lazy-loading, > because I don't think that the small perf difference between going trough= an accessor and accessing a plain property is really relevant > in that context (especially as lazy-loading would have required a method = otherwise). > > What I'd rather see is the reverse behavior: An accessor property shadows= a plain property, so that the plain property is only > accessible from within the accessor methods. This would allow you to writ= e code like in the last example above and I think it would > also make automatic properties more meaningful (you could store the state= in a property with the same name; also nicely integrating > with serialization and debugging). > > I know that you (Clint) want to create a hard distinction between plain p= roperties and accessor properties, but I think that making it > more smooth juts integrated better with PHP. I already noticed several pe= ople who, after reading the RFC, tried to write code where > they access the property from within the accessor. It seems to me that pe= ople think it should work. The current behavior where you > can shadow the accessor property by assigning a property of the same name= seems rather obscure to me. > > This is the feedback I have for now. Looking forward to your thoughts on = the manner. > Nikita I would be interested to see if you could change your analysis code to dete= ct "lazy loading" type use. My own use of __get() is primarily made up of = lazy loading, followed by filtered access (eg: tblEnabledFilters), followed= by aliases to sub-object properties. But in the end I can agree with all of what you've wrote here because lazy = loading could still be implemented as such: public $xyz { get() { return $this->xyz =3D $this->xyz ?: /* Do some loading */ } protected set($x) { $this->xyz =3D $x; } } But here are some issues with the above that may be of concern: * Property access is 4x faster than accessor method calling * This would (without a big change in the current implementation) a= secondary lookup against accessors for every property access o The way around this issue is to *merge* accessors and properties such t= hat the same properties struct that exists now would contain all of the new= properties (or at least a pointer to such.) This may indeed be a much bet= ter way to go anyways. One additional benefit of keeping any backing-field be the same name as the= accessor is that you can more easily mix automatic implementation with non= -automatic, for example the above could simply be left as: public $xyz { get() { return $this->xyz =3D $this->xyz ?: /* Do some loading */ } protected set($x); } --_000_9570D903A3BECE4092E924C2985CE485612B64C8MBX202domainloc_--