NAME
    protocol - Define an API for use by a package

SYNOPSIS
    Define a protocol:

     use protocol;

     protocol My::API;

     use protocol qw(My::Other::API);

     sub foo ($);
     sub bar ($@);

    Use a protocol:

     package My::Implementation;

     use protocol qw(My::API);

    Other methods:

     UNIVERSAL::implements( My::Implementation => 'My::API' );

DESCRIPTION
    This package introduces a new Perl keyword, "protocol", that allows API
    declarations via subroutine prototypes.

    Usually, an algorithm is written to require objects of particular types
    to make sure certain methods are available. This can tie certain
    programs to particular object frameworks, which might not always be the
    best way to write a program. This module tries to correct this by
    allowing interfaces to be defined without creating a class. These
    interface definitions are called `protocols' after the Objective-C
    concept (See Objective-C documentation for more details).

    Protocols not only allow more flexible tracking of implemented APIs, but
    can also aid in the debugging process during module development. Any
    subroutines that are prototyped in a protocol are prototyped in the
    using package. For example, if package A uses protocol B, and protocol B
    defines subroutine C, then A::C will be prototyped. Perl will then issue
    warnings if the subsequent subroutine definition doesn't match the
    prototype given in the protocol definition.

  DEFINING A PROTOCOL

    A protocol is defined in the same way a package is defined, except using
    the "protocol" keyword instead of the "package" keyword:

     use protocol;
     protocol My::SimpleIO::Protocol;

     sub read($);
     sub write($;@);

    You can also sub-class protocols by using them:

     protocol My::MoreAdvanced::IO::Protocol;

     use protocol My::SimpleIO::Protocol;

     sub open($;$);
     sub close($);

    If you want to make sure a method is available but don't care about the
    prototype, you can simply declare it without a prototype:

     protocol My::Sans::Prototype;

     sub foo;
     sub bar;

    Subroutines without prototypes in a protocol won't have any effect
    except when you have an explicit check for the protocol.

  USING A PROTOCOL

    Using a protocol is simple:

     use protocol qw( protocol list );

    This will push the protocol list onto the package global "@PROTOCOLS"
    and prototype any subroutines that have prototypes in the protocols. If
    you want people to think you implement a particular protocol without
    getting the benefit of the prototypes, then push the prototype name onto
    the "@PROTOCOLS" global without the "use" statement. Protocols are not
    expected to load any code.

    Note that a class is considered to implement the protocol if any
    super-class implements the protocol. The class does not gain the benefit
    of the prototypes unless it explicitely "use"s the protocol.

  TRACKING PROTOCOL SUBSCRIPTIONS

    Instead of requiring objects derived from a particular class, you now
    can check that the object implements a particular protocol:

      die "Need to be able to read and write"
           unless $object -> implements("My::IO::Protocol");

    This even works if "$object"'s class doesn't know anything about
    protocols. The "implements" method will look for the actual methods in
    that case and check their signature against the expected signature
    defined in "My::IO::Protocol". If no signature is expected, it checks
    for the method's existance using "UNIVERSAL::can".

    Protocols can co-exist with packages. The package global "@PROTOCOLS" is
    used to track protocol subscriptions similar to the way "@ISA" tracks
    class inheritance. A class has a protocol if it is listed in the
    "@PROTOCOLS" array, is implemented in a super-class, or is implemented
    implicitely in the class.

BUGS
    There are sure to be some. The filter is not the most robust and may be
    easily confused. This is a source filter. Some areas that need
    improvement:

    *   Better error reporting (almost non-existent when defining protocols)

    *   Anything `out of the ordinary' can lead to undefined results (this
        includes code other than simple prototypes in the protocol
        definition).

    *   Any code mixed in to the protocol definition is ignored. The
        protocol definition is replaced by `1;' in the source that Perl sees
        after the filter. This also means that line numbers will be off.

    *   Documentation.

AUTHOR
    James Smith, <jsmith@cpan.org>

COPYRIGHT
    Copyright (C) 2003 Texas A&M University. All Rights Reserved.

    This module is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

