NAME
CXC::Exporter::Util - Tagged Based Exporting
VERSION
version 0.02
SYNOPSIS
In the exporting code:
package My::Exporter;
use CXC::Exporter::Util ':all';
use parent 'Exporter' # or Exporter::Tiny
# install sets of constants, with automatically generated
# enumerating functions
install_CONSTANTS( {
DETECTORS => {
ACIS => 'ACIS',
HRC => 'HRC',
},
AGGREGATES => {
ALL => 'all',
NONE => 'none',
ANY => 'any',
},
} );
# install some functions
install_EXPORTS(
{ fruit => [ 'tomato', 'apple' ],
nut => [ 'almond', 'walnut' ],
} );
In importing code:
# import all of the fruit functions, all of the DETECTORS constants,
# as well as a function enumerating the DETECTORS constants
use My::Exporter ':fruit', ':detector', 'DETECTORS';
# print the DETECTORS constants' values;
say $_ for DETECTORS;
DESCRIPTION
CXC::Exporter::Util provides tag-centric utilities for modules
which export symbols. It doesn't provide exporting services; its sole
purpose is to manipulate the data structures used by exporting modules
which follow the API provided by Perl's core Exporter module
(e.g. Exporter::Tiny).
In particular, it treats %EXPORT_TAGS as the definitive source for
information about exportable symbols and uses it to generate
@EXPORT_OK and @EXPORT. Consolidation of symbol information in
one place avoids errors of omission.
Exporting Symbols
At it simplest, the exporting module calls "install_EXPORTS" with a hash specifying tags and their symbols sets, e.g.,
package My::Exporter;
use CXC::Exporter::Util;
use parent 'Exporter'; # or your favorite compatible exporter
install_EXPORTS(
{ fruit => [ 'tomato', 'apple' ],
nut => [ 'almond', 'walnut' ],
} );
sub tomato {...}
sub apple {...}
sub almond {...}
sub walnut {...}
An importing module could use this via
use My::ExportingModule ':fruit'; # import tomato, apple
use My::ExportingModule ':nut'; # import almond, walnut
use My::ExportingModule ':all'; # import tomato, apple,
# almond, walnut,
For more complicated setups, %EXPORT_TAGS may be specified first:
package My::ExportingModule;
use CXC::Exporter::Util;
use parent 'Exporter';
our %EXPORT_TAGS = ( tag => [ 'Symbol1', 'Symbol2' ] );
install_EXPORTS;
install_EXPORTS may be called multiple times
Exporting Constants
CXC::Exporter::Util provides additional support for creating, organizing and installing constants via "install_CONSTANTS". Constants are created via Perl's constant pragma.
"install_CONSTANTS" is passed one or more hashes containing sets of constants grouped by tags, e.g.:
install_CONSTANTS( {
DETECTORS => {
ACIS => 'ACIS',
HRC => 'HRC',
},
AGGREGATES => {
ALL => 'all',
NONE => 'none',
ANY => 'any',
},
});
# A call to install_EXPORTS (with or without arguments) must follow
# install_CONSTANTS;
install_EXPORTS;
For each set an enumerating function is created which returns the set's values.
In the above example, constant functions ACIS, HRC, ALL,
NONE, ANY, tags detectors and aggregates, and constant
functions DETECTORS and AGGREGATES are created.
The enumerating functions are useful for generating enumerated types via e.g. Type::Tiny:
Enum[ DETECTORS ]
or iterating:
say $_ for DETECTORS;
If the constants are used later in the module for other purposes, constant definition should be done in a BEGIN block:
our %CONSTANTS;
BEGIN { %CONSTANTS = (...);
install_CONSTANTS( \%CONSTANTS );
}
install_CONSTANTS may be called multiple times.
For more complex situations, the lower level "install_constant_tag" and "install_constant_func" routines may be useful.
SUBROUTINES
install_EXPORTS
install_EXPORTS( [\%export_tags], [$package], [\%options] );
Populate $package's @EXPORT and @EXPORT_OK arrays based upon
%EXPORT_TAGS and %export_tags.
If not specified, $package defaults to the caller's package.
Available Options:
-
overwrite => [Boolean]
If the
overwriteoption is true, the contents of%export_tagswill overwrite%EXPORT_TAGSin$package, otherwise%export_tagsis merged into%EXPORT_TAGS.Note that overwriting will wipe out tags and symbols installed by a previous call to "install_CONSTANTS".
This defaults to false.
-
package => [Package Name]
This provides another means of indicating which package to install into. Setting this overrides the optional
$packageargument. -
all => [Boolean | 'auto' ]
This determines whether "install_EXPORTS" creates an
alltag based on the contents of%EXPORT_TAGSin$package. Some exporters, such as Exporter::Tiny and Sub::Exporter automatically handle thealltag, but Perl's default Exporter does not.If set to
auto(the default), it will install thealltag if$packageis not a subclass of Exporter::Tiny.(At present I don't know how to determine if Sub::Exporter is used).
This routine does the following in $package based upon
%EXPORT_TAGS in $package:
- Install the symbols specified via the
$EXPORT_TAGS{default}tag into@EXPORT. - Install all of the symbols in
%EXPORT_TAGSinto@EXPORT_OK.
install_CONSTANTS
install_CONSTANTS( @specs, ?$package );
Create sets of constants and make them available for export in
$package.
If not specified, $package defaults to the caller's package.
The passed @specs arguments are either hashrefs or arrayrefs and
contain one or more constant set specifications. A constant set
specification consists of a unique identifier and a list of name-value
pairs, specified either has a hash or an array. For example,
@spec = ( { $id1 => \%set1, $id2 => \@set2 },
[ $id3 => \%set3, $id4 => \@set4 ],
);
The $id? identifiers are used to create a export tag for the set as
well as an enumerating function which returns the set's values.
The individual $id, $set pairs are passed to install_constant_tag;
see that function for more information.
"install_CONSTANTS" may be called multiple times, and may be used to updated existing sets of constants.
Note that a call to install_EXPORTS must be made after the last
call to install_CONSTANTS or the constants won't be added to the
exports.
install_constant_tag
Create and install constant functions for a set of constants. Called either as
install_constant_tag( [ $tag, $fname], $constants, [$package] )
or as
install_constant_tag( $string, $constants, [$package] )
in which case
( $tag, $fname ) = ( lc($string), $string );
$constants specifies the constants' names and values, and may be
either a hashref or an arrayref containing name - value pairs.
$package is the name of the package (the eventual exporter) into
which the constants will be installed. It defaults to the package of
the caller.
-
use Perl's constant pragma to create a function named name returning value for each name-value pair in
$constants.The functions are installed in
$packageand their names added to the symbols in%EXPORT_TAGSwith export tag$tag. -
use Perl's constant pragma to create an enumerating function named
$fnamewhich returns a list of the values in$constants. If$constantsis an arrayref, the values will be returned in the order specified.If the function
$fnamealready exists, a new function is created (named$fname) which returns the values returned by the original function and the new constant values added by this call to "install_constant_tag".$fnameis added to the symbols in%EXPORT_TAGStagged withcontant_funcs.
For example, after
$id = 'AGGREGATES';
$constants = { ALL => 'all', NONE => 'none', ANY => 'any' };
install_constant_tag( $id, $constants );
-
The constant functions,
ALL,NONE,ANYwill be created and installed in the calling package.A new element will be added to
%EXPORT_TAGSwith an export tag ofaggregates.$EXPORT_TAGS{aggregates} = [ 'ALL', 'NONE', 'ANY ]; -
A function named
AGGREGATESwill be created and installed in the calling package.AGGREGATESwill return the values'all', 'none', 'any'(in a random order, as
$constantsis a hashref).AGGREGATESwill be added to the symbols tagged byconstant_funcsin%EXPORT_TAGS
After this, a package importing from $package can
-
import the constant functions
ALL,NONE,ANYvia theaggregatetag:use Package ':aggregate'; -
import the enumerating function
AGGREGATESdirectly, viause Package 'AGGREGATES'; -
import
AGGREGATESvia theconstant_funcstag:use Package ':constant_funcs';
As mentioned above, if the first argument to "install_constant_tag" is an
arrayref, $tag and $fname may be specified directly. For example,
$id = [ 'Critters', 'Animals' ];
$constants = { HORSE => 'horse', GOAT => 'goat' };
install_constant_tag( $id, $constants );
will create the export tag Critters for the GOAT and HORSE
constant functions and an enumerating function called Animals.
install_constant_tag uses "install_constant_func" to create and install
the constant functions which return the constant values.
Caveat! Because of how enumerating functions are created, specifying new values and a new enumerating function name for an existing tag will not cause the new values to be added to the previous enumerating function. For example,
install_constant_tag( 'TAG', { HIGH => 'high' } );
install_constant_tag( [ 'TAG', 'ATAG' ], { LOW => 'low' } );
Will create a function TAG which returns high and a function
ATAG which returns low. Don't depend upon this behavior.
install_constant_func( $name, \@values, $caller )
This routine does the following in $package, which defaults to the
caller's package.
- Create a constant subroutine named
$namewhich returns@values; - Adds
$nameto theconstant_funcstag in%EXPORT_TAGS.
For example, after calling
install_constant_func( 'AGGREGATES', [ 'all', 'none', 'any' ] );
-
The function
AGGREGATESwill returnall,none,any. -
A package importing from
$packagecan import theAGGREGATEconstant function via theconstant_funcstag:use Package ':constant_funcs';or directly
use Package 'AGGREGATES';
BUGS
No attempt is made to complain if enumerating functions' names clash with constant function names.
EXAMPLES
-
Alternate constant generation modules.
To use an alternate constant generation function bypass install_CONSTANTS and load things manually.
For example, using enum:
package My::Exporter; use CXC::Exporter::Util ':all'; our @DaysOfWeek; BEGIN{ @DaysOfWeek = qw( Sun Mon Tue Wed Thu Fri Sat ) } use enum @DaysOfWeek; use constant DaysOfWeek => map { &$_ } @DaysOfWeek; install_EXPORTS( { days_of_week => \@DaysOfWeek, constant_funcs => [ 'DaysOfWeek' ], });and then
use My::Exporter -days_of_week; say Sun | Mon;
SUPPORT
Bugs
Please report any bugs or feature requests to bug-cxc-exporter-util@rt.cpan.org or through the web interface at: https://rt.cpan.org/Public/Dist/Display.html?Name=CXC-Exporter-Util
Source
Source is available at
https://gitlab.com/djerius/cxc-exporter-util
and may be cloned from
https://gitlab.com/djerius/cxc-exporter-util.git
SEE ALSO
Please see those modules/websites for more information related to this module.
AUTHOR
Diab Jerius djerius@cpan.org
COPYRIGHT AND LICENSE
This software is Copyright (c) 2022 by Smithsonian Astrophysical Observatory.
This is free software, licensed under:
The GNU General Public License, Version 3, June 2007