"Module::PluginFinder" - automatically choose the most appropriate
    plugin module.

     use Module::PluginFinder;

     my $finder = Module::PluginFinder->new(
                     search_path => 'MyApp::Plugin',

                     filter => sub {
                        my ( $module, $searchkey ) = @_;
                        $module->can( $searchkey );

     my $ball = $finder->construct( "bounce" );

     my $fish = $finder->construct( "swim" );

    This module provides a factory class. Objects in this class search for a
    specific plugin module to fit some criteria. Each time a new object is
    to be constructed by the factory, the caller should provide a value
    which in some way indicates the kind of object required. The factory's
    filter function is then used to determine which plugin module fits the

    The most flexible way to determine the required module is to provide a
    filter function. When looking for a suitable module, the function is
    called once for each candidate module, and is passed the module's name
    and the search key. The function can then return a boolean to indicate
    whether the module will be suitable. The value of the search key is not
    directly used by the "Module::PluginFinder" in this case, and therefore
    is not restricted to being a simple scalar value; any sort of reference
    may be passed.

    Instead of a filter function, the factory can inspect a package variable
    or constant method in each of the candidate modules, looking for a
    string match with the search key; see the "typevar" and "typefunc"
    constructor arguments. When using this construction, a map from type
    names to module names will be cached at the time the
    "Module::PluginFinder" object is created, and will therefore not be
    sensitive to changes in the values once this is done. Because of this,
    the key should be a simple string, rather than a reference.

  $finder = Module::PluginFinder->new( %args )
    Constructs a new "Module::PluginFinder" factory object. The constructor
    will search the module path for all available plugins, as determined by
    the "search_path" key and store them.

    The %args hash must take the following keys:

    search_path => STRING or ARRAY
            A string declaring the module namespace, or an array reference
            of module namespaces to search for plugins (passed to

    In order to specify the way candidate modules are selected, one of the
    following keys must be supplied.

    filter => CODE
            The filter function for determining whether a module is suitable
            as a plugin

    typevar => STRING
            The name of a package variable to match against the search key

    typefunc => STRING
            The name of a package method to call to return the type name.
            The method will be called in scalar context with no arguments;

             $type = $module->$typefunc();

            If it returns "undef" or throws an exception, then the module
            will be ignored

  @modules = $finder->modules()
    Returns the list of module names available to the finder.

  $module = $finder->find_module( $searchkey )
    Search for a plugin module that matches the search key. Returns the name
    of the first module for which the filter returns true, or "undef" if no
    suitable module was found.

            A value to pass to the stored filter function.

  $object = $finder->construct( $searchkey, @constructorargs )
    Search for a plugin module that matches the search key, then attempt to
    create a new object in that class. If a suitable module is found to
    match the $searchkey then the "new" method is called on it, passing the
    @constructorargs. If no suitable module is found then an exception is

            A value to pass to the stored filter function.

            A list to pass to the class constructor.

    Perform another search for plugin modules. This method is useful
    whenever new modules may be present since the object was first

    The filter function allows various ways to select plugin modules on
    different criteria. The following examples indicate a few ways to do

  Availability of a function / method
     my $f = Module::PluginFinder->new(
                search_path => ...,

                filter => sub {
                   my ( $module, $searchkey ) = @_;

                   return $module->can( $searchkey );

    Each plugin then simply has to implement the required function or method
    in order to be automatically selected.

  Value of a method call
     my $f = Module::PluginFinder->new(
                search_path => ...,

                filter => sub {
                   my ( $module, $searchkey ) = @_;

                   return 0 unless $module->can( "is_plugin_for" );
                   return $module->is_plugin_for( $searchkey );

    Each plugin then needs to implement a method called "is_plugin_for",
    that should examine the $searchkey and perform whatever testing it
    requires, then return a boolean to indicate if the plugin is suitable.

  Value of a constant
    Because a constant declared by the "use constant" pragma is a plain
    function, it can be called by the "typefunc" filter:

     my $f = Module::PluginFinder->new(
                search_path => ...,

                typefunc => 'PLUGIN_TYPE',

    Each plugin can then declare its type using a constuction like

     use constant PLUGIN_TYPE => "my type here";

    Alternatively, a normal package method may be created that performs any
    work required to determine the plugin's type

     sub PLUGIN_TYPE
        my $class = shift;


        return $typename;

    Note that the type function in each module will only be called once, and
    the returned value cached.

  Value of a package scalar
    The "typevar" constructor argument generates the filter function

     my $f = Module::PluginFinder->new(
                search_path => ...,

                typevar => 'PLUGIN_TYPE',

    Each plugin can then declare its type using a normal "our" scalar

     our $PLUGIN_TYPE = "my type here";

    *   Module::Pluggable - automatically give your module the ability to
        have plugins

    Paul Evans <>