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  --------------------

Reply via email to