Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:35835 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 95778 invoked by uid 1010); 28 Feb 2008 01:47:57 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 95763 invoked from network); 28 Feb 2008 01:47:57 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 28 Feb 2008 01:47:57 -0000 Authentication-Results: pb1.pair.com smtp.mail=andi@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=andi@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 212.25.124.162 as permitted sender) X-PHP-List-Original-Sender: andi@zend.com X-Host-Fingerprint: 212.25.124.162 mail.zend.com Windows 2000 SP4, XP SP1 Received: from [212.25.124.162] ([212.25.124.162:41213] helo=mx1.zend.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 09/8F-14752-AC216C74 for ; Wed, 27 Feb 2008 20:47:57 -0500 Received: from us-ex1.zend.com ([192.168.16.5]) by mx1.zend.com with Microsoft SMTPSVC(6.0.3790.3959); Thu, 28 Feb 2008 03:48:04 +0200 X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Date: Wed, 27 Feb 2008 17:47:59 -0800 Message-ID: <698DE66518E7CA45812BD18E807866CE01506447@us-ex1.zend.net> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: [PHP-DEV] How to build a real Trait thing without exclusion and renaming Thread-Index: Ach35XHIMkXry+++Qa6qMxbnz1bosgBw+0cg References: <47C317F4.2080301@stefan-marr.de> To: , "internals Mailing List" , "Marcus Boerger" X-OriginalArrivalTime: 28 Feb 2008 01:48:04.0115 (UTC) FILETIME=[F541AE30:01C879AB] Subject: RE: [PHP-DEV] How to build a real Trait thing without exclusion and renaming From: andi@zend.com ("Andi Gutmans") > -----Original Message----- > From: Stefan Marr [mailto:php@stefan-marr.de] > Sent: Monday, February 25, 2008 11:33 AM > To: internals Mailing List; Marcus Boerger > Subject: [PHP-DEV] How to build a real Trait thing without exclusion > and renaming > > > //here the new notion of combing traits and resolving conflicts upfront > class Talker { > use A, B { > B::smallTalk instead A::smallTalk; > A::bigTalk instead B::bigTalk; > A::bigTalk as talk; > } > } Hi Stefan, I think the discussion is going in the right direction but personally I had to think really hard to figure out what this code was going to do :) The following is a suggestion which takes into account some of the discussions we've had including points both Lukas and Marcus have made on this list. I have not thought through all of the implementation details but I am quite sure we could implement such behavior. The following code shows a few things: - local properties which can be used in self-contained functionality. The storage is guaranteed to stay internal and will not clash with the aggregating class. - methods are by default hidden to the aggregating class and bound to the trait (as Marcus pointed out the method name would be mangled with the trait's name) - You can expose any method you want either by doing a "use TraitA *" for all methods or by explicitly exposing methods to a specific method in the class. Note: This is the equivalent of aliasing. The original mangled method in the Trait doesn't disappear but you can override it with a new method.=20 Unlike what some have said that this is better solved with MI or Delegation as opposed to Traits I don't subscribe to that. I believe this suggestion still gives you the benefits of copy&paste ala Traits but adds more structure, a more useful ability to encapsulate functionality which is very often the case when Trait like functionality is needed (stateful traits), and most important, I think it's easy to understand and read. trait MyDebug { local $counter =3D 1; function showTrace() { printf("Called this %d time(s)\n", $this->counter++); debug_backtrace(); } } trait MyTicks { local $counter =3D 0; function logIncrement() { // Log when we incremented the counter } function incTicks() { $this->logIncrement(); return $this->counter++; } } class MyClock { use MyDebug *; use MyTicks { timeInTicks =3D inTicks; // Don't want to see logIncrement() } function display() {...} } Andi