Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:63694 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 46244 invoked from network); 28 Oct 2012 16:52:45 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 28 Oct 2012 16:52:45 -0000 Authentication-Results: pb1.pair.com header.from=nikita.ppv@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=nikita.ppv@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.215.42 as permitted sender) X-PHP-List-Original-Sender: nikita.ppv@gmail.com X-Host-Fingerprint: 209.85.215.42 mail-la0-f42.google.com Received: from [209.85.215.42] ([209.85.215.42:48791] helo=mail-la0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 43/C7-18930-CD26D805 for ; Sun, 28 Oct 2012 11:52:45 -0500 Received: by mail-la0-f42.google.com with SMTP id e6so3632545lah.29 for ; Sun, 28 Oct 2012 09:52:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=4iR1re1jYxv5jMdOo2WdGy/YQOHcLj8nzWqDkwPW1DM=; b=HE+6+yRv98hAIxt+zRkTol8t8GQE99myphYbho3RuMLQoQKqvcxuvvFb0SNR9853UJ bCVd6+yrhdtEsEQD4Gp0Jq98030oAbdSGa9G3S6D4ihl4uhsvFGQinaSeNTHe4LUMxen c899qJ0ls5MiWkf3qP8kxgsuPAcYRAi+LeBsqd3Qt9UWNATMk+yNHxEXv5aaKVpVPVK+ 1Tm4sKtfjBDaJ987U2kiYup3bQRJR1BX1DqS1KaWAlUyJHXzU0jfsWEmkzCgn2KN93QX MtcTuyKGMfPAUg5r8fVVRoqTAha/Cjbs2VYJrvGtn09CftQOdk5R3oXwKTcKP9CziPEw w/fw== MIME-Version: 1.0 Received: by 10.152.108.37 with SMTP id hh5mr25182947lab.52.1351443160946; Sun, 28 Oct 2012 09:52:40 -0700 (PDT) Received: by 10.112.83.100 with HTTP; Sun, 28 Oct 2012 09:52:40 -0700 (PDT) In-Reply-To: <508D5462.4070503@zerocue.com> References: <508A67E6.2000405@zerocue.com> <508A9AC9.50200@sugarcrm.com> <508AF3E7.7020004@sugarcrm.com> <508B1EA2.8060203@sugarcrm.com> <508C249D.1000309@zerocue.com> <508C43ED.9000209@sugarcrm.com> <508C80C6.9000008@zerocue.com> <508CD916.1070509@sugarcrm.com> <508D5462.4070503@zerocue.com> Date: Sun, 28 Oct 2012 17:52:40 +0100 Message-ID: To: Clint Priest Cc: Stas Malyshev , PHP Developers Mailing List Content-Type: text/plain; charset=ISO-8859-1 Subject: Re: [PHP-DEV] [RFC] Property Accessors v1.2 : Internal Accessor Method Visibility / Callability From: nikita.ppv@gmail.com (Nikita Popov) On Sun, Oct 28, 2012 at 4:50 PM, Clint Priest wrote: > On 10/28/2012 2:04 AM, Stas Malyshev wrote: >> >> Hi! >> >>> Stas, you should probably do some research before posting such non-sense: >> >> Which part is "non-sense"? I've brought you examples of Python and Ruby >> not doing exactly what you claim all languages are doing. By your >> definition, they don't have accessors - as you define accessors as >> hidden methods that are uncallable and unavailable and not defined as >> regular methods. In both Ruby and Python they are callable and defined >> as regular (or regular with some special attributes) method. >> >> I've brought you examples of popular languages that don't have this >> feature at all - Java and standard C++ don't have it. I was wrong on >> Javascript - though in Javascript, functions work differently from PHP >> so there's no real relation to the current discussion. >> >>> By accessors I am simply referring to getters, setters (and in the case >>> of php, issetter and unsetter). >> >> I wish it was so, but it was mentioned many times in this discussion >> that "accessors should be accessors" and that only the situation where >> accessors are special functions that are not defined as regular methods, >> are not callable and are hidden from reflection, etc. is the situation >> where "accessors are accessors". This is not the case in Python, Ruby, >> MS C++, D and Delphi by your own link - in all these cases, the >> properties are defined as regular methods (possibly with some special >> salt added) and no special effort is taken to hide them from any of the >> language facilities and make them not callable. >> Of course, there are also examples of languages going the other way - >> namely, C#, F# and VB - but by no means the claim that I would be hard >> pressed to find example of the languages which do not implement your >> notion of "accessors being accessors" is true. For most dynamic >> languages, the concept of "accessors being accessors" - hidden, >> non-callable pseudo-methods - is a foreign concept. >> > I see what you're talking about, I felt like you were saying these other > languages did not support accessors (getters, setters, etc). Those other > languages do not "hide" them, no. This was Nikita's suggestion, I will let > her fight for it. If I got it right now, what Stas wants is that we introduce __getFoo and __setFoo methods that will be called whenever an undefined ->foo property is accessed and that the "normal" property accessors syntax is made nothing more than a fancy notation for this. I'm okay with one of those, but I highly advise against combining both, i.e. either __getFoo and __setFoo OR a special accessor syntax. The reason is that both carry different and non-combinable semantics. A few examples: A) Inheritance: ========== class A { public $foo; } class B extends A { public $foo { get() { ... } set($value) { ... } } } => With the accessors syntax there is an expectation that the accessor declaration will override the previous plain property. At least that's what I would expect and that's what the code looks like class A { public $foo; } class B extends A { public function __getFoo() { ... } public function __setFoo($value) { ... } } => With the magic syntax there is the expectation that the $foo property will not be overridden. Rather the magic functions are expected to do nothing, because the property already exists. B) Interfaces: ========= interface A { public $foo; } class B implements A { public $foo { get() { ... } set($value) { ... } } } => Here the accessor is expected to satisfy the interface interface A { public $foo; } class B implements A { public function __getFoo() { ... } public function __setFoo($value) { ... } } => Here the magic methods don't satisfy the interface. Actually with the magic methods approach the whole notion of properties or accessors in interfaces becomes obsolete. C) API semantics ============= The main advantage that accessors offer to me is that custom property behavior can be a *proper part of the public API*. The magic __getFoo / __setFoo methods do not offer this. They are just another two magic methods. On the other hand, proper accessors really define a *property* with a certain behavior (the fact that they are bound to a property is important here). __getFoo and __setFoo are really not much of an improvement over directly using __get and __set with a switch. It's just a small code save. "Real" accessors on the other hand take properties to being a first class API citizen. D) Backing property ============== Additionally __getFoo / __setFoo would not allow us to access $this->foo as the underlying "backing property". Whether or not this approach has merits is a different discussion point, but the magic method approach would make this impossible right from the start. === Point C) is most important to me (and directly related to A and B). I really hope that we will implement proper accessors, rather than some half-hearted implementation using magic methods. Nikita