Mark,
On Dec 5, 2004, at 7:42 PM, Mark Stosberg wrote:
What thoughts do people have on the solution that uses standard export
techniques without extra modules? This is what CGI::Application
Plugins do
now.
This approach is indeed simple to use and understand, but I also think
it has a number limitations.
<disclaimer>
I am not familiar with the details of CGI::Applications's plugins so I
may be off here. My assumption is that the plug-ins import themselves
into the CGI::Application namespace (or a subclass of CGI::Application
maybe).
</disclaimer>
Anyway, this technique has all the frailty of most other mix-in
technologies in that its injecting methods into the class hierarchy in
an arbitrary way. This makes it difficult to have much control over the
hierarchy since at any point a mix-in can just inject functionality
into the middle of it. This also makes debugging difficult since you
now have methods coming at you from all sides. IMO this just gets too
messy and impossible to control in any meaningful way.
If you have a well defined plug-in API and a set of overridable methods
then this can work, since this becomes a predictable thing. But at that
point you are not using general purpose mix-ins, but specific
constrainted plug-ins.
That's it. It's mostly a standard 'has-a' relationship.
A mix-in is not necessarily a has-a relationship. You can use it to
implement such a thing, but usually a mix-in is defined as sort of a
half-hearted is-a relationship. Mix-in classes are many times partial
(deferred) classes (see some of the Python HTTP server classes), so to
call it a true is-a is IMO not correct. When you are combining several
full-classes, I prefer to just call that multiple-inheritance. Although
in practice you can rarely draw clean lines. For instance Simon (in
Text::MicroMason which gave birth to Class::MixinFactory) seemed to
have a combination of whole and partial classes (at least that is what
it seemed like to me after a quick read of the code and several
discussions on perlmonks).
Anyway my point is that many times what you want with a mix-in is an
'is-a' relationship. With the standard export technique this is not
possible.
It can also get messy depending upon the how and when you do things.
Starting with the "how", assuming that you have class A and are mixing
in B.
mixin B {
export "test";
}
class A {
use mixin B;
sub test { ... }
}
Does B.test override A.test? My first guess would be no, since in most
inheritance relationships the local class overrides the superclass.
However looking at this it seems that they did intend to mixin B, which
would include B.test? These is ambiguity here in the syntax and in the
mix-ing in mechanism. The standard export mechanism has no intelligence
built into it so things can quickly get confusing.
Now for the "when". Lets look at this from a different angle:
mixin B {
export "test";
}
class A {
# we do not do the mix-in here anymore
sub test { ... }
}
class C isa A {
sub test {
...
super()
}
}
# some time later in your code
mixin B into A;
Now, I would safely assume that B.test should override A.test. The
explicit mix-in outside of the class makes me assume that. Now in class
C, the super() call would go to B.test and not A.test, which quite
possibly could do things that the author of C is not expecting. This is
a potential maintenance headache, you are getting very quickly into
spaghetti code territory here.
Now these examples may seem trivial, but start mixing in more than one
class and the issues can grow exponetially.
Simon actually explains this stuff and more in the Class::MixinFactory
docs
(http://search.cpan.org/~evo/Class-MixinFactory-0.92/MixinFactory/
ReadMe.pod) Its a good read if you are interested. Also for a more
esoteric bend on all this you can check out the papers on traits
(http://www.iam.unibe.ch/~scg/Research/Traits/), of which I wrote a
perl implementation of
(http://search.cpan.org/~stevan/Class-Trait-0.04/lib/Class/Trait.pm).
- Steve
_______________________________________________
sw-design mailing list
[EMAIL PROTECTED]
http://metaperl.com/cgi-bin/mailman/listinfo/sw-design