Hi
I just want to add a big +1 from an "end user" perspective for traits.
I know from my perspective this would be an incredibly valuable tool
for php. I'm essentially already using the functionality this brings
(as I'm sure many other devs are), albeit in an ugly way - either
adding functionality to a single superclass at the bottom of the class
heirarchy, or using interfaces along with composites/delegation, which
means a lot of unnecessary code duplication.
I've been reading through the threads on the subject -- I'm not sure if
discussion has died because of pressure to get 5.3 out of the door, or
for other reasons, but it seems the conversation stopped without any
real resolution, and the wiki seems to be in a similar state.
It's a great idea in principle, but I've noticed a lot of discussion is
focused on preventing collisions by ignoring/aliasing methods. Maybe
I'm misunderstanding the usage case for traits here, but I envision
them as "working interfaces". The methods of a trait surely shouldn't
change visibiliy/name depending on which class they appear in? Doesn't
that defeat the whole point?
Regarding collisions, If I try to do the following...
interface i1{ public function foo(); }
interface i2{ protected function foo($a,$b); }
interface i3{ public function foo($a,$b,$c,$d); }
class Broken implements i1,i2,i3{ private function foo($a) }
.... I wouldn't expect it to work! It's the developer's job to know the
interface they're implementing. Similarly isn't it the developer's job
to know the methods in a trait, and manage any collisions directly in
their code, not in statements for php to process and
include/exclude/alias things? Moreover, surely it's the developer's
responsibility to use verbose method names (eg 'saveOrder', not
'save'), in the knowledge that the code will be inherited by a class in
which his 'save' method would no longer have any context, and is likely
to collide with existing methods of that class...
My use scenario for a trait would basically be a functional
interface... Since most of the code so far in the discussion on traits
has been all foo's and bar's, I'd like to present a few real-life
examples that I think show the potential use of traits while still
keeping the code compact...
trait Optionable{
protected $_options;
protected function _setOptions($options){
$this->_mergeArrays($this->_options,$options) }
public function getOptions(){ return $this->_options; }
private function _mergeArrays($ar1,$ar2){ }
}
trait Hookable{
private static $registry;
public static function registerHook($type,$object){
self::$registry['...etc...'] } //if methods are copied, I guess it'd
have to be Hookable::$registry
protected function _runActionHooks($data){}
protected function _runFilterHooks($data){}
}
class Something is Optionable, Hookable{
//$_options is a protected property of Optionable, so I expect to
inherit or have a copy...
//$registry is private so I don't expect to see it here
public function __construct($data,$options){
//the following methods are all protected, so I'd expect to inherit
or have them copied with the same visibility
$this->_setOptions($options);
$this->_runActionHooks($data);
$data = $this->_runFilterHooks($data);
}
}
I know this basically resembles multiple inheritance (please don't
cry)... I think the important distinction is firstly one of use - the
keyword distinction between class and 'trait' should be used to
encourage short, reusable bits of code, where multiple inheritance and
the sloppy behaviour that comes with it is not a problem. Secondly, to
prevent it becoming multiple-inheritance-by-another-name I don't
believe traits should be able to inherit from other traits.
I've read through every message on this subject and I still don't see
the benefit being added by all the complexity of adding loads of extra
reserved words & complex include/exclude/alias logic for something
which should surely be a simple fix to a simple problem?
If I'm being naiive and totally missing something, please let me know!
Andru
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php