atcroft has asked for the wisdom of the Perl Monks concerning the following question:

Earlier in the Chatterbox, I asked the following:

<atcroft> Anyone know a good module or tutorial on writing code to have the ability to add functionality using plugins/addons/modules?

There were a few replies mentioning Module::Pluggable, or to look at double dispatch and rolling my own method. So, what are your (insight|opinions|thoughts) on it, or do you have (links|references|specific modules) you can point me to?

(My thanks to LanX, MidLifeXis, and Voronich, for suggesting I post this for response from the larger community.)

Update: 2013-12-30
There have been several comments asking for more detail on what I had in mind. I had wanted to get general feedback, but the (personal) project I have in mind that would use this is a program looking at files dumped into a subdirectory and initially recording a small amount of information, but I wanted a more modular way of adding in additional capabilities for specific file types (for example, have the initial program working, then add in a module for retrieve EXIF information from JPGs in the directory or to process MBOX files at a later date, without having to modify the initial (possibly running) program).

  • Comment on Recommendations for adding plugin/addon capability to a program

Replies are listed 'Best First'.
Re: Recommendations for adding plugin/addon capability to a program
by boftx (Deacon) on Dec 30, 2013 at 19:48 UTC

    I have used both "roll-my-own" and Module::Pluggable with success. It really depends on what I was trying to do.

    That said, I would probably be more inclined to go with M::P now since it offers more flexibility overall, even if not needed at the time. The use-cases I had involved finding what plugins were available so I could process a given input format with a given plugin, converting to an internal virtual format if it existed or bailing out otherwise.

    Some of what I was doing could possibly be done using API Roles in Moose, instead.

    It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re: Recommendations for adding plugin/addon capability to a program
by LanX (Saint) on Dec 30, 2013 at 19:26 UTC
    Like I already said in the CB the question is interesting but abstract.

    Already the terminology "plugin" is hard to define but the alternative "addon" doesn't make it easier.

    And I don't know what "double dispatch" is supposed to mean.

    Could you tell us more about the concrete use case which triggered your question? =)

    Module::Pluggable at least seems to easily cover the use cases I can (theoretically) think of...

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: Recommendations for adding plugin/addon capability to a program
by tobyink (Canon) on Dec 31, 2013 at 07:54 UTC

    I've written about plugins before, the gist of which is that autoloading plugins a la Module::Pluggable is often a bad idea.

    In the long run, rather than automatically scanning for all installed plugins and using them, end users will get more predictable and reliable behaviour if you force them to provide an explicit list of plugins to load. Something like:

    my $person = MyApp::Person->new( name => 'Bob', age => 33, plugins => [ 'FooCorp::Employable', 'Web::Social::Contact', ], );

    I've had a todo for a while that I should write a follow up to my earlier article, showing how to use roles for extensibility. Until I write that, I refer you to MooseX::Traits, and the Role::Tiny documentation to get an idea of how this can be accomplished without Moose.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
Re: Recommendations for adding plugin/addon capability to a program
by Laurent_R (Canon) on Dec 30, 2013 at 21:29 UTC

    OK, now that you have updated your post with more information, I understand better what you are looking for, something like the http://search.cpan.org/~simonw/Module-Pluggable-4.8/lib/Module/Pluggable.pm module might be a good solution.

    Another possibility might be to write a module (or use an existing one such as File::Find::xxx) that explores your directory and possibly subdirectories and you can then pass callback functions to this module to do the functional part of the job. Or even possibly passing an array or a hash of callback functions to the module.

Re: Recommendations for adding plugin/addon capability to a program
by Anonymous Monk on Dec 31, 2013 at 07:49 UTC
Re: Recommendations for adding plugin/addon capability to a program
by boftx (Deacon) on Dec 31, 2013 at 00:09 UTC

    Given the additional information I would agree that Module::Pluggable would be a viable way to go. You can scan in the plugins you have and build a hash of the kinds of file you can handle (with module names as values) and then call as needed for each file type as you encounter them. Each module could have a standard method that would "register" itself in the hash that could be called as part of the M::P search/init routine.

    That is basically what I did for my primary use case. I had to take in various CSV and XML files and call the correct module to transform them into my internal format for further processing.

    It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re: Recommendations for adding plugin/addon capability to a program
by locked_user sundialsvc4 (Abbot) on Dec 31, 2013 at 00:05 UTC

    I would probably use the existing class-hierarchy capabilities of the Perl language, and perhaps the very-goodness of UNIVERSAL::require.

    Your system would stipulate that all plugins must inherit from some base-class (perhaps “among others”) via a use base statement.   It would also require that the modules live in some specified location.   When a new plugin was requested, it would attempt to require the appropriate module, then, if successful in doing that, would perhaps call some class-method to initialize it.

    Okay, for a brass-tacks example of what I am talking about, peruse http://search.cpan.org/~mkanat/RPC-Any-1.00/lib/RPC/Any/Server.pm#HOW_RPC_METHODS_ARE_CALLED which describes a similar “plugin” notion in the context of an RPC-server which loads request-handling modules on demand.   There are many others.   Study the source-code of “live examples” to see exactly how they did it.

Re: Recommendations for adding plugin/addon capability to a program
by Laurent_R (Canon) on Dec 30, 2013 at 20:01 UTC
    I also think it would be easier if you gave a bit more details on what exactly you are trying to achieve.