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/ )}
);
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' }
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() function is the magical interface. It can be used in many forms. The following all work equally well for export_ok().
- our @EXPORT = @names;
- our @EXPORT_OK = @names;
-
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)
-
Export the sub specified by the string $name. This sub must be defined in the current package.
- export($name, sub { ... })
- export_ok($name, sub { ... })
- export name => sub { ... }
- export_ok name => sub { ... }
- export name { ... }
- 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 )
-
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 { ... })
- export name parser { ... }
- 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 ( ... ) { ... }
-
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 ( ... ) { ... }
-
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 )
-
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 { ... })
-
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 )
-
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 { ... })
-
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
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.