NAME Exporter::Declare - Declarative exports and simple Devel-Declare interface. DESCRIPTION Declarative function exporting. You can export subs as usual with @EXPORT, or export anonymous subs under whatever name you want. You can also extend Exporter::Declare very easily. Exporter-Declare also provides a friendly interface to Devel::Declare magic. With Devel::Declare::Parser and its parser library, you can write Devel::Declare enhanced functions without directly using Devel-Declare. Exporter-Declare also supports tags and optional exports just like Exporter. An addtion you can prefix or rename imports at import time. It can be used as a drop-in replacement for exporter for an easy upgrade path. BASIC SYNOPSIS EXPORTING package My::Exporter; use strict; use warnings; use Exporter::Declare; # works as expected our @EXPORT = qw/a/; our @EXPORT_OK = qw/f/; our @EXPORT_TAGS = ( main => \@EXPORT, other => \@EXPORT_OK, mylist => [ ... ], # Bonus! dynamic => sub { $class = shift; return ( qw/a b/ )} ); our $_ID = 1; # Fancy export is generated each time our %GEN_EXPORT_OK = ( ... ); our %GEN_EXPORT = ( importer_id => sub { my ( $exporting_class, $importing_class ) = @_; my $id = _ID++; return sub { $id }; } ); sub a { 'a' } # Declare an anonymous export export b => sub { 'b' }; export( 'c', sub { 'c' }); export 'd'; sub d { 'd' } export_ok 'e'; sub e { 'e' } sub f { 'f' } export_ok g => sub g { 'g' } # declarative generated export { my $alpha = 'A'; # can also use gen_export_ok gen_export unique_alpha => sub { my ( $exporting_class, $importing_class ) = @_; my $uniq = $alpha++; return sub { $uniq }; } } 1; BASIC IMPORTING package My::Consumer; use strict; use warnings; use My::Exporter; a(); #calls My::Consumer::a() e(); # Will die, e() is in export_ok, not export ENHANCED INTERFACE SYNOPSIS Notice, no need for '=> sub', and trailing semicolon is optional. package MyPackage; use strict; use warnings; use Exporter::Declare; # Declare an anonymous export export b { 'b' } export c { 'c' } 1; EXPORTING DEVEL-DECLARE INTERFACES SYNOPSIS To export Devel-Declare magic you specify a parser as a second parameter to export(). Please see the PARSERS section for more information about each parser. package MyPackage; use strict; use warnings; use Exporter::Declare; export sl sublike { # $name and $sub are automatically shifted for you. ... } export mth method { # $name and $sub are automatically shifted for you. ... } export cb codeblock { # $sub is automatically shifted for you. ... } export beg begin { my @args = @_; ... }; # Inject something into the start of the code block export injected method ( inject => 'my $arg2 = shift; ' ) { ... } Then to use those in the importing class: use strict; use warnings; use MyPackage; sl name { ... } mth name { # $self is automatically shifted for you. ... } cb { ... } # Same as BEGIN { beg(@args) }; beg( @args ); MANY FACES OF EXPORT The export functions are the magical interface. They can be used in many forms. This is a complete guide to all forms. In practice a small subset is probably all most tools will use. our @EXPORT = @names; our @EXPORT_OK = @names; our %GEN_EXPORT = ( name => \&generator, ... ); our %GEN_EXPORT_OK = ( name => \&generator, ... ); Technically your not actually using the function here, but it is worth noting that use of a package variable '@EXPORT' works just like Exporter. export($name) export_ok($name) gen_export($name) gen_export_ok($name) Export the sub specified by the string $name. This sub must be defined in the current package. Those with the 'gen_' prefix will treat the referenced sub as a generator. export($name, sub { ... }) export_ok($name, sub { ... }) export name => sub { ... } export_ok name => sub { ... } gen_export($name, sub { ... }) gen_export_ok($name, sub { ... }) gen_export name => sub { ... } gen_export_ok name => sub { ... } export name { ... } export_ok name { ... } gen_export name { ... } gen_export_ok name { ... } Export the coderef under the specified name. In the second 2 forms an ending semicolon is optional, as well name can be quoted in single or double quotes, or left as a bareword. export( $name, $parser ) export_ok( $name, $parser ) gen_export( $name, $parser ) gen_export_ok( $name, $parser ) Export the sub specified by the string $name, applying the magic from the specified parser whenever the function is called by a class that imports it. export( $name, $parser, sub { ... }) export_ok( $name, $parser, sub { ... }) gen_export( $name, $parser, sub { ... }) gen_export_ok( $name, $parser, sub { ... }) export name parser { ... } export_ok name parser { ... } gen_export name parser { ... } gen_export_ok name parser { ... } Export the coderef under the specified name, applying the magic from the specified parser whenever the function is called by a class that imports it. In the second form name and parser can be quoted in single or double quotes, or left as a bareword. export name ( ... ) { ... } export_ok name ( ... ) { ... } gen_export name ( ... ) { ... } gen_export_ok name ( ... ) { ... } same as 'export name { ... }' except that parameters can be passed into the parser. Currently you cannot put any variables in the ( ... ) as it will be evaluated as a string outside of any closures - This may be fixed in the future. Name can be a quoted string or a bareword. export name parser ( ... ) { ... } export_ok name parser ( ... ) { ... } gen_export name parser ( ... ) { ... } gen_export_ok name parser ( ... ) { ... } same as 'export name parser { ... }' except that parameters can be passed into the parser. Currently you cannot put any variables in the ( ... ) as it will be evaluated as a string outside of any closures - This may be fixed in the future. Name and parser can be a quoted string or a bareword. $class->export( $name ) $class->export_ok( $name ) $class->gen_export( $name ) $class->gen_export_ok( $name ) Method form of 'export( $name )'. $name must be the name of a subroutine in the package $class. The export will be added as an export of $class. $class->export( $name, sub { ... }) $class->export_ok( $name, sub { ... }) $class->gen_export( $name, sub { ... }) $class->gen_export_ok( $name, sub { ... }) Method form of 'export( $name, \&code )'. The export will be added as an export of $class. $class->export( $name, $parser ) $class->export_ok( $name, $parser ) $class->gen_export( $name, $parser ) $class->gen_export_ok( $name, $parser ) Method form of 'export( $name, $parser )'. $name must be the name of a subroutine in the package $class. The export will be added as an export of $class. $class->export( $name, $parser, sub { ... }) $class->export_ok( $name, $parser, sub { ... }) $class->gen_export( $name, $parser, sub { ... }) $class->gen_export_ok( $name, $parser, sub { ... }) Method form of 'export( $name, $parser, \&code )'. The export will be added as an export of $class. IMPORTER SYNOPSIS NORMAL package MyThing; use MyThingThatExports; CUSTOMISING package My::Consumer; use strict; use warnings; use My::Exporter qw/ a !f :prefix:my_ :other !:mylist /, { a => 'apple' }; apple(); #calls My::Consumer::a(), renamed via the hash above f(); # Will die, !f above means do not import my_g(); # calls My::Consumer::e(), prefix applied, imported via :other 1; 'export_name' If you list an export it will be imported (unless it appears in a negated form) '!export_name' The export will not be imported { export_name => 'new_name' } Rename an import. ':prefix:VALUE' Specify that all imports should be renamed with the given prefix, unless they are already renamed via a rename hash. ':tag' '!:tag' Import all the exports listed by $EXPORT_TAGS{tag}. ! will negate the list. all tag names are valid unless they conflict with a specal keyword such as 'prefix' or 'extend'. Extending (Writing your own Exporter-Declare) Doing this will make it so that importing your package will not only import your exports, but it will also make the importing package capable of exporting subs. package MyExporterDeclare; use strict; use warnings; use Exporter::Declare ':extend'; export my_export export { my ( $name, $sub ) = @_; export( $name, $sub ); } PARSERS Writing custom parsers See Devel::Declare::Parser Provided Parsers Devel::Declare::Parser::Export Used for functions that export, accepting a name, a parser, and options. Devel::Declare::Parser::Sublike Things that act like 'sub name {}' Devel::Declare::Parser::Method Same ad Sublike except codeblocks have $self automatically shifted off. Devel::Declare::Parser::Codeblock Things that take a single codeblock as an arg. Like defining sub mysub(&) except that you do not need a semicolon at the end. Devel::Declare::Parser::Begin Define a sub that works like 'use' in that it runs at compile time (like wrapping it in BEGIN{}) This requires Devel::BeginLift. FENNEC PROJECT This module is part of the Fennec project. See Fennec for more details. Fennec is a project to develop an extendable and powerful testing framework. Together the tools that make up the Fennec framework provide a potent testing environment. The tools provided by Fennec are also useful on their own. Sometimes a tool created for Fennec is useful outside the greator framework. Such tools are turned into their own projects. This is one such project. Fennec - The core framework The primary Fennec project that ties them all together. AUTHORS Chad Granum exodist7@gmail.com COPYRIGHT Copyright (C) 2010 Chad Granum Exporter-Declare is free software; Standard perl licence. Exporter-Declare is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.