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

Reply via email to