Hi, Stefan,
Thanks for considering my ideas so carefully and for your detailed
replies.
The reason to go with insteadof is that the assignment syntax hides
changes that might cause problems.
Thus, when you change any of the traits participating in a composition
in a way that a conflict would be introduced, the assignment syntax is
hiding this. With the insteadof syntax you are actually forced to
reevaluate whether your code still makes sense and include the
offending change explicitly.
OK. That makes sense. I'll rework any surviving parts of my proposal to
be based on the insteadof syntax.
This does not only have the mentioned benefit of making problematic
changes in the traits hierarchy explicit, but the second reason to go
with this design was the wish to have a 'exclude' operator without
actually having a full-exclude operator. Thus, there is no way that
you can leave out arbitrary methods from a trait.
This seems wrong to me. Doesn't it go against the stated principle that
the class author should have full control of traits? How is it full
control if you can't exclude a method? What is the reasoning behind this
wish not to have a full exclude operator?
Hm, don't understand you here either. I needed to look up what
impoverished actually means, you are not insulting me here, right?
Just kidding ;)
Sorry. I forget that a lot of you people aren't native English speakers
and sometimes funny words like that slip in! I think all you people who
communicate so fluently in additional languages are amazing.
No error or warning will be
generated, but the class will not work as intended; probably it will
infinitely recurse; a nasty problem to track down.
Furthermore, even if the incorrect method call didn't occur, there would
be data-sharing problems, as both the ErrorReporting trait and the
class' print() function make use of the $output data member,
unintentially sharing data.
Well, short answer: it is compiler-assisted copy-and-past, why isn't
that trait just providing the glue that gets your class the necessary
functionality to use a proper ErrorReporting class?
Sorry, I know not a really helpful answer, but I hope that examples
shows how I see traits.
They are for reusing code in situations where the other concepts just
break down. Not meant to replace those.
I agree. I did say it was a poor example. I think the kinds of
behavioural problems it demonstrates, though, could be found in
situations where traits *are* truly appropriate.
No need to argue over examples, though. Plenty of other things to argue
about. :-)
Warnings
- - - -
To avoid silent unintended shadowing, I suggest issuing a warning when a
conflict between trait and class methods occurs. So this would trigger
a warning:
trait SaySomething {
public function sayIt() {
echo "Something\n";
}
}
class Sayer {
use SaySomething;
public function sayIt() {
echo "Hello world!\n";
}
}
Ok, well, we could see the actual class body as another trait, and
require it to follow the same composition rules, and that way make
require the programmer to use insteadof in such a case.
In return that would mean, that traits are not part of the inheritance
chain at all anymore.
Thus, first is the inheritance chain used to build up the
implementation of a class, and afterwards all the traits are composed,
while the original class is seen as another trait.
That idea has certainly something to it.
Yes, I think that would be good.
Having read your other emails, as well as having allowed my proposal
itself to clarify in my mind, I'm beginning to think it might be
clearest and cleverest to avoid inheritance altogether with traits. Of
course, this is in contrast to my original proposal, which was to
increase traits' participation in inheritance.
In this case, parent:: will always do what you expect then, and there's
no need for prev::.
Now to the other emails!
Ben.
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php