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