Eric Wilhelm wrote:
It is still difficult to debug, regardless of hope or intent. If the
user breaks something via their config, a loud and obvious error should
result.
Two problems: Just because a pre hook decided to override the method,
and there were other pre hooks that didn't get called, it doesn't prove
that anything's wrong. Perhaps the processing that those hooks would
have done is unnecessary in this case. I don't see any way for Perl to
decide. I suppose we could print a warning, but what if a maintainer
picks 2 plugins that cause that warning, but he knows that it's ok? How
can he suppress the warning? (Maybe we should print the warning only if
the overriding hook came from a system/user plugin.)
Second, my primary goal is that a plugin should be able to do anything a
subclass can do. This includes creating situations that are very
difficult to debug. The only way to make something impossible to abuse
is to make it too restricted to do many things that would be useful.
Similarly, maybe the priority should simply be by load-order. At least
then a plugin which knows it is incompatible with another can make
noise. Still it might be nice to have the noise created via some
mechanism in the registration (e.g. "conflicts => {Foo => '<= 0.2'}".)
One problem is that conflicts probably wouldn't be discovered until both
plugins have been released. A conflicts mechanism wouldn't do anything
to help people who only installed the initial release. I don't recall
ever seeing M::B's conflicts mechanism actually used.
Load-order would be sufficient for plugins in Build.PL, although that
means we'd have to use an arrayref instead of a hashref like everything
else uses.
For the system config, I suppose we could split it in two sections:
higher priority than Build.PL and lower priority than Build.PL. But
then the user config would need 4 sections:
1. Higher than system
2. Between system & Build
3. Between Build & system
4. Lower than Build
And what about plugins specified on the command line?
Maybe the short-circuit (bypassing/replacing the default method) should
just be defined differently. That is: replace_METHOD() or something
and only allow one definition of it.
The problem is that a pre hook may want to override the default method
only for certain input parameters. And another pre hook might want to
override for other input parameters. All-or-nothing is too restrictive.
A few concrete examples would certainly help me work through that logic.
A pre hook is the equivalent of this method in a subclass:
sub method {
my $self = shift;
... do stuff ...
if (want to override) { return $something }
$self->SUPER::method(@_); # @_ might have been modified
}
A post hook is the equivalent of this:
sub method {
my $self = shift;
my $return = $self->SUPER::method(@_); # I'm ignoring context here
... do stuff ...
return $return; # Might be modified
}
If you want to do stuff before and after SUPER::method, you install both
hooks. (Plugins aren't completely identical to this, because all post
hooks get called even if a pre hook decided to override. But they're
close.)
--
Chris Madsen [EMAIL PROTECTED]
-------------------- http://www.cjmweb.net --------------------