There is a phenomenon, all too frequent, known as "object-oriented
disease." It occurs when a programmer, overly enamored of the concept
of object-oriented programming, creates a large number of object types
and abstraction boundaries. Most of these abstractions tend not to serve
any practical purpose, but exist to fit the programmer's idea of a
computer science ideal. The resulting programs end up being
unmaintainable, as new programmers need to make an enormous effort to
understand all of the gratuitous layers of abstraction.
SpamAssassin is in serious danger of contracting "plugin disease." The
fact that people are seriously talking about making
PerMsgStatus::check() a plugin is Exhibit A. The idea is itself a
reduction to absurdity.
Plugins are quite useful, but they have a cost: each plugin adds to the
complexity of configuration and thus adds to the set of possible failure
modes. They also replace Perl's hierarchical namespace with a flat
namespace unrelated to the filesystem layout, making it harder to find code.
This came out of discussions at ApacheCon where we decided to get rid of
EvalTests, which means the code had to become plugins. The layout of things
in tvd-evaltoplugin is not final, it's just a working version that doesn't
have EvalTests.
I recall that there was an observation on the dev list that the
EvalTests.pm had a different API than plugin-provided eval tests. It is
worth making the APIs the same and it is possibly worth having those
tests registered with the same mechanism that calls eval tests, but
making it possible to fail by not loading those tests is not a good idea.
You either have 1 big plugin, which may as well be EvalTests, or you have
many plugins, one for each function. The current split is somewhere in the
middle where I tried grouping semi-related functions together by rule type.
One big plugin would be better than the current split. The current
split has no solid technical rationale behind it.
A key facet of plugins is that they are optional. For something to be
correctly designed as a plugin, it must make sense for the plugin to be
loaded and it must make sense for the plugin to not be loaded.
Not really. A key facet of plugins is that someone may turn off or
replace the functionality to avoid or change behavior, overhead, etec.
There's no requirement that the functionality be optional.
I think we mostly agree on this point. If it makes sense to replace the
functionality of a plugin, then it makes sense for the plugin to not be
loaded.
The split-out plugins I object to fail to meet your stated key facet.
Sure. There was talk about completely plugin-izing Bayes, this could
be considered a first step.
If the branch were completely plugin-izing Bayes, that would be a
different matter. Bayes should either be "completely" plugin or it
should be completely core. The proposed half-measure merely adds
additional configuration-dependent failure modes.
I fear Bayes has semantics that may interact too closely with the core
to make it a good plugin. The interaction of Bayes with score set
selection suggests it really is core. One can already disable Bayes,
avoiding its overhead. I remain skeptical.
the EvalTests to match those of plugins. It does not, however, make
sense to have the loading of those eval tests be optional.
Actually, that doesn't make sense. ;)
No useful purpose is served by providing the user/administrator the
option of not loading the proposed plugins in question.
There's nothing special about
these eval rules that makes them necessary to the functionality of the
software. In fact, there was talk that some/a bunch would go away due
to results anyway.
Those eval rules are used by the models distributed by SpamAssassin;
failing to load them will break the assumptions upon which the models
were built.
If results show that some should be removed, then they should be removed
outright. If someone wants to run their own model which excludes some
number of these tests, they can do so with the more straightforward
facility of setting their weights to zero.