NAME
     Plugins::API - Inter-plugin callback API

SYNOPSIS
     use Plugins::API;

     my $api = new Plugins::API;

     $api->api( methodname1 => \%options1, methodname2 => \%options2, ... );

     $api->plugins ($plugins_object);

     @handlers = $api->handlers;

     $api->invoke('methodname', @args);

     $api->autoregister($self);

     $api->register($self, [\%options], methodname1 => \&method1, methodname2 => \&method2, ...)

     $api->disable('ClassName');
     $api->disable($object);

DESCRIPTION
    Plugins::API provides a framework for modules to rendevous with each
    other at runtime. It's designed to work with the Plugins module but it
    does not depend upon Plugins and could be used without it.

    The basic idea is that you describe a invocation interface with the
    "api()" method and then you register methods for later callback. A
    method callback requires an object (unless it's a class method) and when
    you register a method, Plugins::API keeps a reference to the object for
    use when making the callback.

    A registered method is called a *handler* in the rest of this document.

METHODS
    Plugins::API objects are created with the "new()" method so that will be
    documented first:

    new([\%options,] [@api])
        Options for "new()" are passed as a reference to a hash. It's
        optional. Also option is an interface specification like what is
        passed to the "api()" method (below).

        The options supported are:

        autoregister => $self
                       Automaticlly register class methods (see
                       "autoregister()" below).

        plugins => $plugins
                       Just like calling "plugins()" (below).

    api(%interface)
        The "api()" call creates the published interfaces that Plugins::API
        users use to invoke each other.

        Pass in key/value pairs. The key is the interface name and the value
        is a refernece to a hash of options for that callback. The supported
        options are:

        first_only => 1
            If there are handlers for this callback only call the first one
            on the list.

        first_defined => 1
            If there are multiple handlers for this callback, call them in
            sequence until one of them returns a value that is not undef.
            This only works in scalar context.

        combine_returns => 1
            If there are multiple handlers for this callback, call them all
            in sequence and return a flattened list of all the return
            values.

        array_returns => 1
            When invoked, return an array whose elements are references to
            arrays which are the return values from each of the handlers for
            this callback.

        exit_test => \&test_function
            After each call to a handler for this callback, call the
            test_function to see if we should stop invoking more handlers:

             ($quit_if_true, @return_value) = test_function(
                    \@last_handler_return, 
                    \@array_of_handler_returns,
                    \@flattend_array_of_handler_returns,
                    wantarray)

    autoregister($self)
        Autoregister will compare the methods of $self to the callbacks
        defined by "api()" and register $self's methods as handlers if any
        of $self's methods have the same name as a callback.

    register($self, [\%options,] %handlers)
        Register binds methods to the interface. Pass in callback names as
        keys and code references as values. It is not required that the API
        method name was not previously defined.

        If $self is undefined then the code references will be called as
        functions rather than methods.

        The options supported by "register()" are:

        first     Normally new handlers are added to the end of the list of
                  handlers for the callback. With this option, the handlers
                  will be added to the beginning of the list.

        replace   Normally new handlers are added to the end of the list of
                  handlers for the callback. With this option, the handlers
                  will replace the current list.

    invoke($callback, [@args)
        This causes all of the handlers for $callback to be called in turn
        and the return value from the last handler to be returned. Some of
        this behavior can be changed with calls to "api()".

        Plugins::API has an "AUTOLOAD" function that hands off to
        "invoke()". Thus all callbacks look like they're methods for
        Plugins::API.

    disable($object) =item disable('CLASS')
        Handlers can be turned off with "disable()". Turning off a class
        disables all objects in the class. There is no re-enable function at
        this time.

    plugins($plugins)
        Plugins::API works with the Plugins module. If a Pluginss object has
        been registered with "plugins()", then any "invoke()" of a callback
        also do a "Plugins::invoke()" on the $plugins object.

    handlers($callback)
        This returns a list of the un-disabled handlers for a callback.
        Handlers are objects in the Plugins::API::Handler class. They
        support the following methods:

        call(@args)
            Call the function or method with @args.

        object()
            Return the object or class that the function is a method for.
            Returns an empty list if there is no object or class.

        method()
            Returns a code reference for the function.

EXAMPLES
    See the code for SyslogScan::Daemon::SpamDetector.

MEMORY LEAKS
    Plugins::API uses "Scalar::Util::weaken()" on object referneces and on
    $plugins so that it will not cause reference loops.

RESERVED METHOD NAMES
    Since Plugins::API uses "AUTOLOAD" so that you can say

     $api->foobar()

    where "foobar" is a callback, you need to avoid naming your callbacks
    the same as Plugins::API methods. In addition to the methods documented
    above, please don't have callbacks named:

     callhandlers()
     newhandler()

SEE ALSO
    Plugins

THANK THE AUTHOR
    If you find this module useful and wish to show your appreciation to the
    author, please give me a Request-For-Quote on your next high-speed
    internet pipe order. I have good pricing for T1s, T3s, OC3s etc.

LICENSE
    Copyright (C) 2006, David Muir Sharnoff <muir@idiom.com>. This module
    may be used and redistributed on the same terms as Perl itself.

