NB: Nothing in this is helpful for the solution of the problem, it's just some OO stuff I've been thinking about.
I'd say the problem is a lack of specificity, not just when you call SUPER but in all methods calls. What does $self->shoot do? If $self is a soccer player then we can expect a ball to be kicked at the goal but if $self is a gunslinger then we can expect an injury. Problems arise when $self is a person who knows how to play football and shoot a gun. In this case, what is the meaning of $self->shoot? This sort of problem is why mixins are viewed as a bad thing but I think this can be solved the same way we've solved other name clashes.
We have namespaces for so many things but not for methods. If we had namespaces for methods then we could write $self->SoccerPlayer::shoot. Of course we wouldn't actually want to write that because it's a pain, we'd want to write
and if our language is smart enough we won't even need to write the "treat as" most of the time, it will be obvious because this is a method for the SoccerPlayer mixin.treat $self as SoccerPlayer; # do lots of soccer playery things with $self $self->shoot;
Amazingly enough, depite being a huge bag of suckiness Borland's Object Pascal (the laguage inside Delphi) incorporates something vaguely like this, except without any smartness or help from the compiler. In it's interface dispatch setup you can tell it that method soccer_shoot implements shoot when we're being treated as soccerplayer and method gunslinger_shoot implements shoot when we're being treated as a gunslinger. Of course the designers then went and ruined it by not allowing mixins. They provide a way to disambiguate methods based on context but then limit your ways of sharing methods among classes.
Delegation and composition lead to lots of boilerplate delegation methods (which you can autogenerate if you're lucky) and it leads to situations where the subobject method calls have to be passed in a reference to their parent object so that they can manipulate it. For example a gunslinger may have a reload() method which looks in the persons various pockets for bullets and loads the gun so the delegation method in Person looks like
and the other reload method looks likesub reload { $self->gunslingerimplementer->reload($self) }
Then there's the question of where does the gun live. If it lives inside the gunslinger object then it makes it hard for the parent to manipulate it. If it lives inside the person object then it's an extra bit of stuff I need to remember when I'm adding gunslingability to my person. With mixins, we can set it up so that we get a gun field along with the relevant methods.sub reload($parent) { my $bullets = $parent->pockets->getbullets(6); $parent->gun->load($bullets); }
So it's possible to have mixins without the usual problems and I think it would work very nicely (SUPER would go up to correct chain of classes), except that no language that I know of implements namespaced-methods.
In reply to Re^2: Solving the SUPER problem in Mixins with a Dispatch Method
by fergal
in thread Solving the SUPER problem in Mixins with a Dispatch Method
by simonm
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |