> -----Original Message----- > From: Stefan Marr [mailto:[EMAIL PROTECTED] > 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. 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 = 1; function showTrace() { printf("Called this %d time(s)\n", $this->counter++); debug_backtrace(); } } trait MyTicks { local $counter = 0; function logIncrement() { // Log when we incremented the counter } function incTicks() { $this->logIncrement(); return $this->counter++; } } class MyClock { use MyDebug *; use MyTicks { timeInTicks = inTicks; // Don't want to see logIncrement() } function display() {...} } Andi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php