Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:61917 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 71495 invoked from network); 1 Aug 2012 12:26:44 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Aug 2012 12:26:44 -0000 Authentication-Results: pb1.pair.com header.from=php@stefan-marr.de; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=php@stefan-marr.de; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain stefan-marr.de from 81.20.134.149 cause and error) X-PHP-List-Original-Sender: php@stefan-marr.de X-Host-Fingerprint: 81.20.134.149 vps-1012701-4512.united-hoster.de Received: from [81.20.134.149] ([81.20.134.149:53761] helo=vps-1012701-4512.united-hoster.de) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id BA/96-32875-28029105 for ; Wed, 01 Aug 2012 08:26:43 -0400 Received: from [134.184.43.20] by vps-1012701-4512.united-hoster.de with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1SwY0b-0001NH-F5; Wed, 01 Aug 2012 14:26:39 +0200 Mime-Version: 1.0 (Apple Message framework v1084) Content-Type: text/plain; charset=us-ascii X-Priority: 3 In-Reply-To: <2125641B4C7D4D6E8616F86C9C5563D2@pc> Date: Wed, 1 Aug 2012 14:26:36 +0200 Cc: Content-Transfer-Encoding: quoted-printable Message-ID: <5D98E000-D40D-43EC-9C94-D5B00331C82E@stefan-marr.de> References: <232501B15F7F4B3197123F219370E36D@pc> <2125641B4C7D4D6E8616F86C9C5563D2@pc> To: Stan Vass X-Mailer: Apple Mail (2.1084) Subject: Re: [PHP-DEV] Traits behavior still up in the air in 5.4 From: php@stefan-marr.de (Stefan Marr) Hi Stan: On 01 Aug 2012, at 13:54, Stan Vass wrote: >> The methods in the class have *always* higher precedence. >> This is the same 'overriding' behavior used for inheritance. >> =46rom my personal perspective, changing this would lead to a major = inconsistency with how subclassing works. >=20 > Hi, I've subsequently read your RFC carefully and saw some of those = items are by design. However while they're by design, the end result = seems rather confusing I should say. >=20 > While I'm glad the RFC was shooting for consistency in general, traits = are not subclassing. Therefore aligning the behavior of features for = vertical reuse with features for horizontal reuse seems somewhat = arbtirary to me. Horizontal reuse is 'fit into' the hierarchy of things: 1. super class 2. horizontal reuse 3. actual class =46rom that follows that traits override the super class's methods. And, conflict resolution is only done between traits, not between a = class and its traits. The class body is a definite thing. Why would you purposefully add = something to a class body that conflicts with a trait? The class needs to know exactly what the traits are doing. There is no = black-box reuse. > The use cases for overriding methods like this seem sketchy at best. = What is the use case, and how are those use cases more important than = the confusion caused by allowig this? I don't see your problem. Can you please elaborate with an example = (other than your initial one? The use case for overriding is typically that you got a conflict that = you need to resolve by making a call to both conflicting methods. Consider two traits that happen to provide a log() function, and in the = resulting class you need to call both in all places log() has been = called before. Since the user of these traits is the only place where such semantic is = sensibly defined, the method in the class body is overriding the traits = methods, and can access aliases you introduced for the traits' methods. >>> 2. Using "as" syntax when importing a trait does NOT rename a = method, but creates an alias CLONE, the original method still callable. >>> Proposed behavior: the original name should be only accessible = within the trait and its methods, not from the class methods or by = calling the class instance's methods from outside. >=20 >> Again, this happens to be 'by design'. >> PHP is a rather dynamic language, and we happen to have things like = $c->$foo(); >> where $foo is a string. Renaming is technically not reasonable, and = would also lead to major confusion when metaprogramming is used. > Can you please explain how are function names by variable at all = related to this? $object->foo() and $object->$foo() aren't even related = in any way semantically. If a conflict exists while grafting a trait, = the original method will be overshadowed silently and the method will be = only accessible by the alias. The entire idea of aliasing is to avoid a = conflict with an existing method of the same name. While if there's no = collision, it's accessible by both. So in practice it works by chance. = How is "working by chance" in any way aiding meta programming? Let's use your example and make something more complex out of it: trait T { function bar(){ $this->print(); $str =3D 'print'; $this->$str(); } function print() { echo 'trait'; } } class C { use T { print as foo; } } What is supposed to happen in this example if we assume renaming? Would you expect the first function call to print() in bar() to work = after the renaming? Would you expect the second call, using metaprogramming, to work as = well? If we use aliasing instead of renaming, we have predictable behavior for = all options. foo just happens to be another alias for print. If print is conflicting with something else, the conflict can be = resolved, but print() is still going to be called reliably. If you do = renaming, it will be partial, and you will get foo() called one time, = and print() the other time. >=20 >>> 3. Properties silently collide in traits and classes. >> Please read = https://wiki.php.net/rfc/horizontalreuse#handling_of_propertiesstate = carefully. >>=20 >> Again, this is intended behavior. >> If you want to be notified of such collisions, please use E_STRICT. >=20 > I've read them carefully now, but there's no solid reason given for = this behavior, or why the proper behavior only exists in E_STRICT. > I can't really see "state is a complex topic" as a reason why trait = property collisions are handles inconsistently with method collisions. Please do me the favor and consult the mailing list archives. It is all in the various discussions. There is no proper way to handle state, state requires splitting, = merging, and what not. None of the research prototypes provides a simple = solution. The solution we have is a 'best effort' solution. If you can do better, please make a proposal. >>> 4. The documentation says static propeties can't be defined by = traits. Yet they can. >>>=20 >>> I don't know what's the bug here: a doc bug, or a code bug. For = consistency, static properties should work, if instance properties work. = Nothing is gained supporting it half-way. >=20 >> Could you please point me *exactly* to the paragraph where we have = something written about static properties? I do not see that I wrote = anything special about static properties in the >RFC. And I do not find = it in the docs either. static properties should work like normal = properties. >=20 > Sure. =46rom the manual page for traits: "Static variables can be = referred to in trait methods, but cannot be defined by the trait." > This paragraph is then following by a code example using = function-static variables as what seems like an example for a = replacement for static trait properties, strongly suggesting the former = aren't supported. Yet they are. >=20 > The RFC seems to also give examples of method-level static variables, = and I honestly can't see how this is related to traits or = trait/class-level members at all. I assume we are talking about: = http://php.net/manual/en/language.oop5.traits.php Static variables and members/properties are not related at all. The = writer of the documentation didn't get the wording correct. Please feel = free to submit a patch. The example code given in the manual is correct. (Example #9 Static = Variables) The section heading is misleading. It is not about static members, and = members and variables are not synonym. Members are synonym with = properties, and properties can be static. Static variables are local to a class, not to a trait. Traits do not exist at runtime, they are flattened into classes. With regard to your other mail. I didn't get a bug report with the keyword trait in it. If you want me to clarify the confusion, please give me a link. Best regards Stefan >=20 > Stan=20 >=20 > --=20 > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >=20 --=20 Stefan Marr Software Languages Lab Vrije Universiteit Brussel Pleinlaan 2 / B-1050 Brussels / Belgium http://soft.vub.ac.be/~smarr Phone: +32 2 629 2974 Fax: +32 2 629 3525