Gustaf Neumann neumann@wu-wien.ac.at wrote on 09/07/2006 10:24:35 AM:
Scott Gargash schrieb:
Thanks, but in my particular case I don't have knowledge of Derived, only Base. By that, I mean I'm actually adding BaseMixin (the HW simulator) to Base (the HW) before Derived has even been created. I'd
like for Derived to remain ignorant of BaseMixin because BaseMixin only exists for testing purposes. I prefer to avoid having code paths
that exist only for testing purposes. (Which mixins are particualrly well-suited for).
well, that are your requirements, but for others it might be different.
Agreed. Except I don't understand the scenario where the current behavior is desirable.
If mixins intercepted at the class they were mixed into, then you have the ability to choose precisely where you want the mixin to intercept:
That could be globally by adding the mixin at the head: ::Derived mixin add ::BaseMixin ==> ::BaseMixin ::Derived ::Base
Or at an intermediate location by adding the mixin lower in the stack ::Base mixin add ::BaseMixin ==> ::Derived ::BaseMixin ::Base
But the current definition only allows for the first case, irrespective of where the developer places the mixin. I can understand why someone might want to intercept Derived, but if that's what they want they should have to be explicit about it, no? Implicitly intercepting classes you don't have knowledge of seems to be asking for errors.
At least that's how I found out how this works...
Do you have a technical reason, why you want the instmixin BaseMixin in
the
precedence order between Base and Derived? I have developed many applications with mixins/instmixin, and i never had this need.
::Base ==> Class that manipulates HW device ::Derived ==> Derived class that adds application-specific methods to the HW device. ::BaseMixin ==> HW Simulator
Since BaseMixin simulates HW that Base would actually access, BaseMixin terminates (some) call chains (doesn't invoke 'next'). If BaseMixin is put in front of ::Derived, this keeps those ::Derived methods from being invoked. If BaseMixin invokes 'next', the HW is (incorrectly) accessed. If ::Derived is made aware of BaseMixin, then there's code in the release application dealing with BaseMixin, which won't exist in the release application (BaseMixin simulates HW for test purposes).
I'm sure that this is the appropriate precedence order. I'm not sure that mixins are the appropriate solution. Or rather, I was sure but since enough people don't share my belief that this is an issue I suspect I'm misusing it somehow.
Implementing a simulator as a mixin seemed like a good idea. The application has no reference to the simulator (::Derived -superclass ::Base), and the test harness can mixin the simulator as necessary (::Base mixin add ::BaseMixin) without touching the rest of the application. It just doesn't work.
I can accept that it doesn't work the way I want, but I'm still struggling with why it works the way it does. I don't see the advantage of always forcing the mixin to the head of the precedence, even ahead of classes that haven't been defined yet. My expectation was that when I added a mixin to a particular class, I would intercept methods at the point I added the mixin. Why is my expectation inappropriate?