Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:64559 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 97000 invoked from network); 5 Jan 2013 21:03:13 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 5 Jan 2013 21:03:13 -0000 Authentication-Results: pb1.pair.com header.from=steve@mrclay.org; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=steve@mrclay.org; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain mrclay.org from 50.22.11.19 cause and error) X-PHP-List-Original-Sender: steve@mrclay.org X-Host-Fingerprint: 50.22.11.19 bedford.accountservergroup.com Linux 2.6 Received: from [50.22.11.19] ([50.22.11.19:33925] helo=bedford.accountservergroup.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A4/16-62408-01598E05 for ; Sat, 05 Jan 2013 16:03:12 -0500 Received: from ip68-101-74-66.ga.at.cox.net ([68.101.74.66]:57856 helo=[192.168.11.20]) by bedford.accountservergroup.com with esmtpsa (TLSv1:DHE-RSA-AES256-SHA:256) (Exim 4.80) (envelope-from ) id 1TratZ-0007Vq-Dx for internals@lists.php.net; Sat, 05 Jan 2013 15:03:09 -0600 Message-ID: <50E8950C.1080102@mrclay.org> Date: Sat, 05 Jan 2013 16:03:08 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: internals@lists.php.net References: <50E41BB6.4030901@zerocue.com> <50E4A43E.6030302@zerocue.com> <50E4B232.5000505@mrclay.org> <50E4BDDE.8050509@zerocue.com> <50E4D0BB.7060701@mrclay.org> <50E4FA09.7030001@zerocue.com> <50E529B6.1050903@sugarcrm.com> <50E593DF.9090004@mrclay.org> <50E60994.4000400@sugarcrm.com> <50E86BBB.2080104@mrclay.org> <50E8797C.7030203@zerocue.com> In-Reply-To: <50E8797C.7030203@zerocue.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - bedford.accountservergroup.com X-AntiAbuse: Original Domain - lists.php.net X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mrclay.org Subject: Re: [PHP-DEV] [PHP-RFC] Property Accessors 1.2 for Final Review before Vote From: steve@mrclay.org (Steve Clay) On 1/5/13 2:05 PM, Clint Priest wrote: > I like the alternate idea here, but I'm not sure what advantage it has over the current > situation? See the "Pros" I listed. The primary being a clear differentiation between calling accessors and handling of the storage value associated with the property. > if an accessor is > already "in the call chain" then it will not be called again and "standard property rules" > take effect. I see that as not simpler, and in fact leading to small bugs whenever getters/setters start becoming complex enough to call outside methods. Consider this: class Foo { public $bar = 2 { get { return $this->calcBar(); } } public function calcBar() { return $this->bar * 3; } } echo $foo->bar; // 6 Within calcBar, "$this->bar" is the raw property (2), because hidden state has "unwrapped" (if you will) the property. echo $foo->calcBar(); // 18 But here, within the first call of calcBar "$this->bar" triggers the getter. Now, of course, this is a foolish implementation, but within any method that could be called from the getter/setter, the symbol $this->bar could mean two completely different things; I think this is bad. If, as I proposed, the storage var were only accessible as $prop in the accessor scopes, that would force authors to pass $prop to any supporting methods, clarifying intent. $this->bar would *always* be accessor calls. In this model, I think infinite-loop-causing recursions would be easier to spot. If absolutely necessary we could always throw a fatal error whenever a getter was called twice in the same call chain. Steve >> AFAICT C# strictly separates fields ("properties" in PHP) and properties (a set of >> accessors that emulate a field). >> >> So the RFC provides 3 features (using C# terms): >> 1. A property API >> 2. A built-in storage variable so you don't need a separate field >> 3. Access to the storage variable as if it were a field of the same name >> >> I think #2 is useful, avoiding the need to make a separate field just to make properties >> read-only or type-hinted. However I think the complexity and confusion we're running >> into is mostly caused by #3. >> >> I think we might be better served by having another way to access this storage variable. >> >> What if instead, we have the storage var available as $prop inside all the accessors? >> These would be the default implementations: >> >> get { return $prop; } >> set($value) { $prop = $value; } >> isset { return $prop !== NULL; } >> unset { $prop = NULL; } >> >> Pros: >> * Makes clear that $prop is regular var access, and that $this->PropertyName *always* >> goes through accessors >> * Gives isset/unset full access to the storage var, which allows doing things that can't >> be done via setter/getter. E.g. you could actually implement a property being "unset", >> which would be different from having it set to NULL. >> >> Cons: >> * Allows "evil", like having reads affect the storage var. >> * Allows authors to hang themselves with recursive accessor calls, BUT those mistakes >> would be apparent from looking at the code. >> >> What functionality possible in the RFC would be lost by this? >> >> Steve Clay > Steve Clay -- http://www.mrclay.org/