Initial Commit
This commit is contained in:
116
database/perl/vendor/lib/Exporter/Shiny.pm
vendored
Normal file
116
database/perl/vendor/lib/Exporter/Shiny.pm
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
package Exporter::Shiny;
|
||||
|
||||
use 5.006001;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Exporter::Tiny ();
|
||||
|
||||
our $AUTHORITY = 'cpan:TOBYINK';
|
||||
our $VERSION = '1.002002';
|
||||
|
||||
sub import {
|
||||
my $me = shift;
|
||||
my $caller = caller;
|
||||
|
||||
(my $nominal_file = $caller) =~ s(::)(/)g;
|
||||
$INC{"$nominal_file\.pm"} ||= __FILE__;
|
||||
|
||||
if (@_ == 2 and $_[0] eq -setup)
|
||||
{
|
||||
my (undef, $opts) = @_;
|
||||
@_ = @{ delete($opts->{exports}) || [] };
|
||||
|
||||
if (%$opts) {
|
||||
Exporter::Tiny::_croak(
|
||||
'Unsupported Sub::Exporter-style options: %s',
|
||||
join(q[, ], sort keys %$opts),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ref($_) && Exporter::Tiny::_croak('Expected sub name, got ref %s', $_) for @_;
|
||||
|
||||
no strict qw(refs);
|
||||
push @{"$caller\::ISA"}, 'Exporter::Tiny';
|
||||
push @{"$caller\::EXPORT_OK"}, @_;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Exporter::Shiny - shortcut for Exporter::Tiny
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Exporter::Shiny qw( foo bar );
|
||||
|
||||
Is a shortcut for:
|
||||
|
||||
use base "Exporter::Tiny";
|
||||
push our(@EXPORT_OK), qw( foo bar );
|
||||
|
||||
For compatibility with L<Sub::Exporter>, the following longer syntax is
|
||||
also supported:
|
||||
|
||||
use Exporter::Shiny -setup => {
|
||||
exports => [qw( foo bar )],
|
||||
};
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a very small wrapper to simplify using L<Exporter::Tiny>.
|
||||
|
||||
It does the following:
|
||||
|
||||
=over
|
||||
|
||||
=item * Marks your package as loaded in C<< %INC >>;
|
||||
|
||||
=item * Pushes any function names in the import list onto your C<< @EXPORT_OK >>; and
|
||||
|
||||
=item * Pushes C<< "Exporter::Tiny" >> onto your C<< @ISA >>.
|
||||
|
||||
=back
|
||||
|
||||
It doesn't set up C<< %EXPORT_TAGS >> or C<< @EXPORT >>, but there's
|
||||
nothing stopping you doing that yourself.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report any bugs to
|
||||
L<http://rt.cpan.org/Dist/Display.html?Queue=Exporter-Tiny>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
This module is just a wrapper around L<Exporter::Tiny>, so take a look
|
||||
at L<Exporter::Tiny::Manual::QuickStart> and
|
||||
L<Exporter::Tiny::Manual::Exporting> for further information on what
|
||||
features are available.
|
||||
|
||||
Other interesting exporters: L<Sub::Exporter>, L<Exporter>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
|
||||
|
||||
=head1 COPYRIGHT AND LICENCE
|
||||
|
||||
This software is copyright (c) 2014, 2017 by Toby Inkster.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=head1 DISCLAIMER OF WARRANTIES
|
||||
|
||||
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
508
database/perl/vendor/lib/Exporter/Tiny.pm
vendored
Normal file
508
database/perl/vendor/lib/Exporter/Tiny.pm
vendored
Normal file
@@ -0,0 +1,508 @@
|
||||
package Exporter::Tiny;
|
||||
|
||||
use 5.006001;
|
||||
use strict;
|
||||
use warnings; no warnings qw(void once uninitialized numeric redefine);
|
||||
|
||||
our $AUTHORITY = 'cpan:TOBYINK';
|
||||
our $VERSION = '1.002002';
|
||||
our @EXPORT_OK = qw< mkopt mkopt_hash _croak _carp >;
|
||||
|
||||
sub _croak ($;@) { require Carp; my $fmt = shift; @_ = sprintf($fmt, @_); goto \&Carp::croak }
|
||||
sub _carp ($;@) { require Carp; my $fmt = shift; @_ = sprintf($fmt, @_); goto \&Carp::carp }
|
||||
|
||||
my $_process_optlist = sub
|
||||
{
|
||||
my $class = shift;
|
||||
my ($global_opts, $opts, $want, $not_want) = @_;
|
||||
|
||||
while (@$opts)
|
||||
{
|
||||
my $opt = shift @{$opts};
|
||||
my ($name, $value) = @$opt;
|
||||
|
||||
($name =~ m{\A\!(/.+/[msixpodual]*)\z}) ?
|
||||
do {
|
||||
my @not = $class->_exporter_expand_regexp($1, $value, $global_opts);
|
||||
++$not_want->{$_->[0]} for @not;
|
||||
} :
|
||||
($name =~ m{\A\!(.+)\z}) ?
|
||||
(++$not_want->{$1}) :
|
||||
($name =~ m{\A[:-](.+)\z}) ?
|
||||
push(@$opts, $class->_exporter_expand_tag($1, $value, $global_opts)) :
|
||||
($name =~ m{\A/.+/[msixpodual]*\z}) ?
|
||||
push(@$opts, $class->_exporter_expand_regexp($name, $value, $global_opts)) :
|
||||
# else ?
|
||||
push(@$want, $opt);
|
||||
}
|
||||
};
|
||||
|
||||
sub import
|
||||
{
|
||||
my $class = shift;
|
||||
my $global_opts = +{ @_ && ref($_[0]) eq q(HASH) ? %{+shift} : () };
|
||||
$global_opts->{into} = caller unless exists $global_opts->{into};
|
||||
|
||||
my @want;
|
||||
my %not_want; $global_opts->{not} = \%not_want;
|
||||
my @args = do { no strict qw(refs); @_ ? @_ : @{"$class\::EXPORT"} };
|
||||
my $opts = mkopt(\@args);
|
||||
$class->$_process_optlist($global_opts, $opts, \@want, \%not_want);
|
||||
|
||||
my $permitted = $class->_exporter_permitted_regexp($global_opts);
|
||||
$class->_exporter_validate_opts($global_opts);
|
||||
|
||||
for my $wanted (@want)
|
||||
{
|
||||
next if $not_want{$wanted->[0]};
|
||||
|
||||
my %symbols = $class->_exporter_expand_sub(@$wanted, $global_opts, $permitted);
|
||||
$class->_exporter_install_sub($_, $wanted->[1], $global_opts, $symbols{$_})
|
||||
for keys %symbols;
|
||||
}
|
||||
}
|
||||
|
||||
sub unimport
|
||||
{
|
||||
my $class = shift;
|
||||
my $global_opts = +{ @_ && ref($_[0]) eq q(HASH) ? %{+shift} : () };
|
||||
$global_opts->{into} = caller unless exists $global_opts->{into};
|
||||
$global_opts->{is_unimport} = 1;
|
||||
|
||||
my @want;
|
||||
my %not_want; $global_opts->{not} = \%not_want;
|
||||
my @args = do { our %TRACKED; @_ ? @_ : keys(%{$TRACKED{$class}{$global_opts->{into}}}) };
|
||||
my $opts = mkopt(\@args);
|
||||
$class->$_process_optlist($global_opts, $opts, \@want, \%not_want);
|
||||
|
||||
my $permitted = $class->_exporter_permitted_regexp($global_opts);
|
||||
$class->_exporter_validate_unimport_opts($global_opts);
|
||||
|
||||
my $expando = $class->can('_exporter_expand_sub');
|
||||
$expando = undef if $expando == \&_exporter_expand_sub;
|
||||
|
||||
for my $wanted (@want)
|
||||
{
|
||||
next if $not_want{$wanted->[0]};
|
||||
|
||||
if ($wanted->[1])
|
||||
{
|
||||
_carp("Passing options to unimport '%s' makes no sense", $wanted->[0])
|
||||
unless (ref($wanted->[1]) eq 'HASH' and not keys %{$wanted->[1]});
|
||||
}
|
||||
|
||||
my %symbols = defined($expando)
|
||||
? $class->$expando(@$wanted, $global_opts, $permitted)
|
||||
: ($wanted->[0] => sub { "dummy" });
|
||||
$class->_exporter_uninstall_sub($_, $wanted->[1], $global_opts)
|
||||
for keys %symbols;
|
||||
}
|
||||
}
|
||||
|
||||
# Called once per import/unimport, passed the "global" import options.
|
||||
# Expected to validate the options and carp or croak if there are problems.
|
||||
# Can also take the opportunity to do other stuff if needed.
|
||||
#
|
||||
sub _exporter_validate_opts { 1 }
|
||||
sub _exporter_validate_unimport_opts { 1 }
|
||||
|
||||
# Called after expanding a tag or regexp to merge the tag's options with
|
||||
# any sub-specific options.
|
||||
#
|
||||
sub _exporter_merge_opts
|
||||
{
|
||||
my $class = shift;
|
||||
my ($tag_opts, $global_opts, @stuff) = @_;
|
||||
|
||||
$tag_opts = {} unless ref($tag_opts) eq q(HASH);
|
||||
_croak('Cannot provide an -as option for tags')
|
||||
if exists $tag_opts->{-as} && ref $tag_opts->{-as} ne 'CODE';
|
||||
|
||||
my $optlist = mkopt(\@stuff);
|
||||
for my $export (@$optlist)
|
||||
{
|
||||
next if defined($export->[1]) && ref($export->[1]) ne q(HASH);
|
||||
|
||||
my %sub_opts = ( %{ $export->[1] or {} }, %$tag_opts );
|
||||
$sub_opts{-prefix} = sprintf('%s%s', $tag_opts->{-prefix}, $export->[1]{-prefix})
|
||||
if exists($export->[1]{-prefix}) && exists($tag_opts->{-prefix});
|
||||
$sub_opts{-suffix} = sprintf('%s%s', $export->[1]{-suffix}, $tag_opts->{-suffix})
|
||||
if exists($export->[1]{-suffix}) && exists($tag_opts->{-suffix});
|
||||
$export->[1] = \%sub_opts;
|
||||
}
|
||||
return @$optlist;
|
||||
}
|
||||
|
||||
# Given a tag name, looks it up in %EXPORT_TAGS and returns the list of
|
||||
# associated functions. The default implementation magically handles tags
|
||||
# "all" and "default". The default implementation interprets any undefined
|
||||
# tags as being global options.
|
||||
#
|
||||
sub _exporter_expand_tag
|
||||
{
|
||||
no strict qw(refs);
|
||||
|
||||
my $class = shift;
|
||||
my ($name, $value, $globals) = @_;
|
||||
my $tags = \%{"$class\::EXPORT_TAGS"};
|
||||
|
||||
return $class->_exporter_merge_opts($value, $globals, $tags->{$name}->($class, @_))
|
||||
if ref($tags->{$name}) eq q(CODE);
|
||||
|
||||
return $class->_exporter_merge_opts($value, $globals, @{$tags->{$name}})
|
||||
if exists $tags->{$name};
|
||||
|
||||
return $class->_exporter_merge_opts($value, $globals, @{"$class\::EXPORT"}, @{"$class\::EXPORT_OK"})
|
||||
if $name eq 'all';
|
||||
|
||||
return $class->_exporter_merge_opts($value, $globals, @{"$class\::EXPORT"})
|
||||
if $name eq 'default';
|
||||
|
||||
$globals->{$name} = $value || 1;
|
||||
return;
|
||||
}
|
||||
|
||||
# Given a regexp-like string, looks it up in @EXPORT_OK and returns the
|
||||
# list of matching functions.
|
||||
#
|
||||
sub _exporter_expand_regexp
|
||||
{
|
||||
no strict qw(refs);
|
||||
our %TRACKED;
|
||||
|
||||
my $class = shift;
|
||||
my ($name, $value, $globals) = @_;
|
||||
my $compiled = eval("qr$name");
|
||||
|
||||
my @possible = $globals->{is_unimport}
|
||||
? keys( %{$TRACKED{$class}{$globals->{into}}} )
|
||||
: @{"$class\::EXPORT_OK"};
|
||||
|
||||
$class->_exporter_merge_opts($value, $globals, grep /$compiled/, @possible);
|
||||
}
|
||||
|
||||
# Helper for _exporter_expand_sub. Returns a regexp matching all subs in
|
||||
# the exporter package which are available for export.
|
||||
#
|
||||
sub _exporter_permitted_regexp
|
||||
{
|
||||
no strict qw(refs);
|
||||
my $class = shift;
|
||||
my $re = join "|", map quotemeta, sort {
|
||||
length($b) <=> length($a) or $a cmp $b
|
||||
} @{"$class\::EXPORT"}, @{"$class\::EXPORT_OK"};
|
||||
qr{^(?:$re)$}ms;
|
||||
}
|
||||
|
||||
# Given a sub name, returns a hash of subs to install (usually just one sub).
|
||||
# Keys are sub names, values are coderefs.
|
||||
#
|
||||
sub _exporter_expand_sub
|
||||
{
|
||||
my $class = shift;
|
||||
my ($name, $value, $globals, $permitted) = @_;
|
||||
$permitted ||= $class->_exporter_permitted_regexp($globals);
|
||||
|
||||
no strict qw(refs);
|
||||
|
||||
my $sigil = "&";
|
||||
if ($name =~ /\A([&\$\%\@\*])(.+)\z/) {
|
||||
$sigil = $1;
|
||||
$name = $2;
|
||||
if ($sigil eq '*') {
|
||||
_croak("Cannot export symbols with a * sigil");
|
||||
}
|
||||
}
|
||||
my $sigilname = $sigil eq '&' ? $name : "$sigil$name";
|
||||
|
||||
if ($sigilname =~ $permitted)
|
||||
{
|
||||
my $generatorprefix = {
|
||||
'&' => "_generate_",
|
||||
'$' => "_generateScalar_",
|
||||
'@' => "_generateArray_",
|
||||
'%' => "_generateHash_",
|
||||
}->{$sigil};
|
||||
|
||||
my $generator = $class->can("$generatorprefix$name");
|
||||
return $sigilname => $class->$generator($sigilname, $value, $globals) if $generator;
|
||||
|
||||
my $sub = $class->can($name);
|
||||
return $sigilname => $sub if $sub;
|
||||
|
||||
# Could do this more cleverly, but this works.
|
||||
if ($sigil ne '&') {
|
||||
my $evalled = eval "\\${sigil}${class}::${name}";
|
||||
return $sigilname => $evalled if $evalled;
|
||||
}
|
||||
}
|
||||
|
||||
$class->_exporter_fail(@_);
|
||||
}
|
||||
|
||||
# Called by _exporter_expand_sub if it is unable to generate a key-value
|
||||
# pair for a sub.
|
||||
#
|
||||
sub _exporter_fail
|
||||
{
|
||||
my $class = shift;
|
||||
my ($name, $value, $globals) = @_;
|
||||
return if $globals->{is_unimport};
|
||||
_croak("Could not find sub '%s' exported by %s", $name, $class);
|
||||
}
|
||||
|
||||
# Actually performs the installation of the sub into the target package. This
|
||||
# also handles renaming the sub.
|
||||
#
|
||||
sub _exporter_install_sub
|
||||
{
|
||||
my $class = shift;
|
||||
my ($name, $value, $globals, $sym) = @_;
|
||||
|
||||
my $into = $globals->{into};
|
||||
my $installer = $globals->{installer} || $globals->{exporter};
|
||||
|
||||
$name =
|
||||
ref $globals->{as} ? $globals->{as}->($name) :
|
||||
ref $value->{-as} ? $value->{-as}->($name) :
|
||||
exists $value->{-as} ? $value->{-as} :
|
||||
$name;
|
||||
|
||||
return unless defined $name;
|
||||
|
||||
my $sigil = "&";
|
||||
unless (ref($name)) {
|
||||
if ($name =~ /\A([&\$\%\@\*])(.+)\z/) {
|
||||
$sigil = $1;
|
||||
$name = $2;
|
||||
if ($sigil eq '*') {
|
||||
_croak("Cannot export symbols with a * sigil");
|
||||
}
|
||||
}
|
||||
my ($prefix) = grep defined, $value->{-prefix}, $globals->{prefix}, q();
|
||||
my ($suffix) = grep defined, $value->{-suffix}, $globals->{suffix}, q();
|
||||
$name = "$prefix$name$suffix";
|
||||
}
|
||||
|
||||
my $sigilname = $sigil eq '&' ? $name : "$sigil$name";
|
||||
|
||||
# if ({qw/$ SCALAR @ ARRAY % HASH & CODE/}->{$sigil} ne ref($sym)) {
|
||||
# warn $sym;
|
||||
# warn $sigilname;
|
||||
# _croak("Reference type %s does not match sigil %s", ref($sym), $sigil);
|
||||
# }
|
||||
|
||||
return ($$name = $sym) if ref($name) eq q(SCALAR);
|
||||
return ($into->{$sigilname} = $sym) if ref($into) eq q(HASH);
|
||||
|
||||
no strict qw(refs);
|
||||
our %TRACKED;
|
||||
|
||||
if (ref($sym) eq 'CODE' and exists &{"$into\::$name"} and \&{"$into\::$name"} != $sym)
|
||||
{
|
||||
my ($level) = grep defined, $value->{-replace}, $globals->{replace}, q(0);
|
||||
my $action = {
|
||||
carp => \&_carp,
|
||||
0 => \&_carp,
|
||||
'' => \&_carp,
|
||||
warn => \&_carp,
|
||||
nonfatal => \&_carp,
|
||||
croak => \&_croak,
|
||||
fatal => \&_croak,
|
||||
die => \&_croak,
|
||||
}->{$level} || sub {};
|
||||
|
||||
# Don't complain about double-installing the same sub. This isn't ideal
|
||||
# because the same named sub might be generated in two different ways.
|
||||
$action = sub {} if $TRACKED{$class}{$into}{$sigilname};
|
||||
|
||||
$action->(
|
||||
$action == \&_croak
|
||||
? "Refusing to overwrite existing sub '%s::%s' with sub '%s' exported by %s"
|
||||
: "Overwriting existing sub '%s::%s' with sub '%s' exported by %s",
|
||||
$into,
|
||||
$name,
|
||||
$_[0],
|
||||
$class,
|
||||
);
|
||||
}
|
||||
|
||||
$TRACKED{$class}{$into}{$sigilname} = $sym;
|
||||
|
||||
no warnings qw(prototype);
|
||||
$installer
|
||||
? $installer->($globals, [$sigilname, $sym])
|
||||
: (*{"$into\::$name"} = $sym);
|
||||
}
|
||||
|
||||
sub _exporter_uninstall_sub
|
||||
{
|
||||
our %TRACKED;
|
||||
my $class = shift;
|
||||
my ($name, $value, $globals, $sym) = @_;
|
||||
my $into = $globals->{into};
|
||||
ref $into and return;
|
||||
|
||||
no strict qw(refs);
|
||||
|
||||
my $sigil = "&";
|
||||
if ($name =~ /\A([&\$\%\@\*])(.+)\z/) {
|
||||
$sigil = $1;
|
||||
$name = $2;
|
||||
if ($sigil eq '*') {
|
||||
_croak("Cannot export symbols with a * sigil");
|
||||
}
|
||||
}
|
||||
my $sigilname = $sigil eq '&' ? $name : "$sigil$name";
|
||||
|
||||
if ($sigil ne '&') {
|
||||
_croak("Unimporting non-code symbols not supported yet");
|
||||
}
|
||||
|
||||
# Cowardly refuse to uninstall a sub that differs from the one
|
||||
# we installed!
|
||||
my $our_coderef = $TRACKED{$class}{$into}{$name};
|
||||
my $cur_coderef = exists(&{"$into\::$name"}) ? \&{"$into\::$name"} : -1;
|
||||
return unless $our_coderef == $cur_coderef;
|
||||
|
||||
my $stash = \%{"$into\::"};
|
||||
my $old = delete $stash->{$name};
|
||||
my $full_name = join('::', $into, $name);
|
||||
foreach my $type (qw(SCALAR HASH ARRAY IO)) # everything but the CODE
|
||||
{
|
||||
next unless defined(*{$old}{$type});
|
||||
*$full_name = *{$old}{$type};
|
||||
}
|
||||
|
||||
delete $TRACKED{$class}{$into}{$name};
|
||||
}
|
||||
|
||||
sub mkopt
|
||||
{
|
||||
my $in = shift or return [];
|
||||
my @out;
|
||||
|
||||
$in = [map(($_ => ref($in->{$_}) ? $in->{$_} : ()), sort keys %$in)]
|
||||
if ref($in) eq q(HASH);
|
||||
|
||||
for (my $i = 0; $i < @$in; $i++)
|
||||
{
|
||||
my $k = $in->[$i];
|
||||
my $v;
|
||||
|
||||
($i == $#$in) ? ($v = undef) :
|
||||
!defined($in->[$i+1]) ? (++$i, ($v = undef)) :
|
||||
!ref($in->[$i+1]) ? ($v = undef) :
|
||||
($v = $in->[++$i]);
|
||||
|
||||
push @out, [ $k => $v ];
|
||||
}
|
||||
|
||||
\@out;
|
||||
}
|
||||
|
||||
sub mkopt_hash
|
||||
{
|
||||
my $in = shift or return;
|
||||
my %out = map +($_->[0] => $_->[1]), @{ mkopt($in) };
|
||||
\%out;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=for stopwords frobnicate greps regexps
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Exporter::Tiny - an exporter with the features of Sub::Exporter but only core dependencies
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package MyUtils;
|
||||
use base "Exporter::Tiny";
|
||||
our @EXPORT = qw(frobnicate);
|
||||
sub frobnicate { ... }
|
||||
1;
|
||||
|
||||
package MyScript;
|
||||
use MyUtils "frobnicate" => { -as => "frob" };
|
||||
print frob(42);
|
||||
exit;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Exporter::Tiny supports many of Sub::Exporter's external-facing features
|
||||
including renaming imported functions with the C<< -as >>, C<< -prefix >> and
|
||||
C<< -suffix >> options; explicit destinations with the C<< into >> option;
|
||||
and alternative installers with the C<< installer >> option. But it's written
|
||||
in only about 40% as many lines of code and with zero non-core dependencies.
|
||||
|
||||
Its internal-facing interface is closer to Exporter.pm, with configuration
|
||||
done through the C<< @EXPORT >>, C<< @EXPORT_OK >> and C<< %EXPORT_TAGS >>
|
||||
package variables.
|
||||
|
||||
If you are trying to B<write> a module that inherits from Exporter::Tiny,
|
||||
then look at:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
L<Exporter::Tiny::Manual::QuickStart>
|
||||
|
||||
=item *
|
||||
|
||||
L<Exporter::Tiny::Manual::Exporting>
|
||||
|
||||
=back
|
||||
|
||||
If you are trying to B<use> a module that inherits from Exporter::Tiny,
|
||||
then look at:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
L<Exporter::Tiny::Manual::Importing>
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report any bugs to
|
||||
L<http://rt.cpan.org/Dist/Display.html?Queue=Exporter-Tiny>.
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
B<< IRC: >> support is available through in the I<< #moops >> channel
|
||||
on L<irc.perl.org|http://www.irc.perl.org/channels.html>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Simplified interface to this module: L<Exporter::Shiny>.
|
||||
|
||||
Other interesting exporters: L<Sub::Exporter>, L<Exporter>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
|
||||
|
||||
=head1 COPYRIGHT AND LICENCE
|
||||
|
||||
This software is copyright (c) 2013-2014, 2017 by Toby Inkster.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=head1 DISCLAIMER OF WARRANTIES
|
||||
|
||||
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
134
database/perl/vendor/lib/Exporter/Tiny/Manual/Etc.pod
vendored
Normal file
134
database/perl/vendor/lib/Exporter/Tiny/Manual/Etc.pod
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
=pod
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=for stopwords frobnicate greps regexps
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Exporter::Tiny::Manual::Etc - odds and ends
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=head2 Utility Functions
|
||||
|
||||
Exporter::Tiny is itself an exporter!
|
||||
|
||||
These functions are really for internal use, but can be exported if you
|
||||
need them:
|
||||
|
||||
=over
|
||||
|
||||
=item C<< mkopt(\@array) >>
|
||||
|
||||
Similar to C<mkopt> from L<Data::OptList>. It doesn't support all the
|
||||
fancy options that Data::OptList does (C<moniker>, C<require_unique>,
|
||||
C<must_be> and C<name_test>) but runs about 50% faster.
|
||||
|
||||
=item C<< mkopt_hash(\@array) >>
|
||||
|
||||
Similar to C<mkopt_hash> from L<Data::OptList>. See also C<mkopt>.
|
||||
|
||||
=back
|
||||
|
||||
=head2 History
|
||||
|
||||
L<Type::Library> had a bunch of custom exporting code which poked coderefs
|
||||
into its caller's stash. It needed this to be something more powerful than
|
||||
most exporters so that it could switch between exporting Moose, Mouse and
|
||||
Moo-compatible objects on request. L<Sub::Exporter> would have been capable,
|
||||
but had too many dependencies for the Type::Tiny project.
|
||||
|
||||
Meanwhile L<Type::Utils>, L<Types::TypeTiny> and L<Test::TypeTiny> each
|
||||
used the venerable L<Exporter.pm|Exporter>. However, this meant they were
|
||||
unable to use the features like L<Sub::Exporter>-style function renaming
|
||||
which I'd built into Type::Library:
|
||||
|
||||
## import "Str" but rename it to "String".
|
||||
use Types::Standard "Str" => { -as => "String" };
|
||||
|
||||
And so I decided to factor out code that could be shared by all Type-Tiny's
|
||||
exporters into a single place: Exporter::TypeTiny.
|
||||
|
||||
As of version 0.026, Exporter::TypeTiny was also made available as
|
||||
L<Exporter::Tiny>, distributed independently on CPAN. CHOCOLATEBOY had
|
||||
convinced me that it was mature enough to live a life of its own.
|
||||
|
||||
As of version 0.030, Type-Tiny depends on Exporter::Tiny and
|
||||
Exporter::TypeTiny is being phased out.
|
||||
|
||||
=head2 Obligatory Exporter Comparison
|
||||
|
||||
Exporting is unlikely to be your application's performance bottleneck, but
|
||||
nonetheless here are some comparisons.
|
||||
|
||||
B<< Comparative sizes according to L<Devel::SizeMe>: >>
|
||||
|
||||
Exporter 217.1Kb
|
||||
Sub::Exporter::Progressive 263.2Kb
|
||||
Exporter::Tiny 267.7Kb
|
||||
Exporter + Exporter::Heavy 281.5Kb
|
||||
Exporter::Renaming 406.2Kb
|
||||
Sub::Exporter 701.0Kb
|
||||
|
||||
B<< Performance exporting a single sub: >>
|
||||
|
||||
Rate SubExp ExpTiny SubExpProg ExpPM
|
||||
SubExp 2489/s -- -56% -85% -88%
|
||||
ExpTiny 5635/s 126% -- -67% -72%
|
||||
SubExpProg 16905/s 579% 200% -- -16%
|
||||
ExpPM 20097/s 707% 257% 19% --
|
||||
|
||||
(Exporter::Renaming globally changes the behaviour of Exporter.pm, so could
|
||||
not be included in the same benchmarks.)
|
||||
|
||||
B<< (Non-Core) Dependencies: >>
|
||||
|
||||
Exporter -1
|
||||
Exporter::Renaming 0
|
||||
Exporter::Tiny 0
|
||||
Sub::Exporter::Progressive 0
|
||||
Sub::Exporter 3
|
||||
|
||||
B<< Features: >>
|
||||
|
||||
ExpPM ExpTiny SubExp SubExpProg
|
||||
Can export code symbols............. Yes Yes Yes Yes
|
||||
Can export non-code symbols......... Yes Yes
|
||||
Groups/tags......................... Yes Yes Yes Yes
|
||||
Export by regexp.................... Yes Yes
|
||||
Bang prefix......................... Yes Yes
|
||||
Allows renaming of subs............. Yes Yes Maybe
|
||||
Install code into scalar refs....... Yes Yes Maybe
|
||||
Can be passed an "into" parameter... Yes Yes Maybe
|
||||
Can be passed an "installer" sub.... Yes Yes Maybe
|
||||
Config avoids package variables..... Yes
|
||||
Supports generators................. Yes Yes
|
||||
Sane API for generators............. Yes Yes
|
||||
Unimport............................ Yes
|
||||
|
||||
(Certain Sub::Exporter::Progressive features are only available if
|
||||
Sub::Exporter is installed.)
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Exporter::Shiny>,
|
||||
L<Exporter::Tiny>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
|
||||
|
||||
=head1 COPYRIGHT AND LICENCE
|
||||
|
||||
This software is copyright (c) 2013-2014, 2017 by Toby Inkster.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=head1 DISCLAIMER OF WARRANTIES
|
||||
|
||||
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
266
database/perl/vendor/lib/Exporter/Tiny/Manual/Exporting.pod
vendored
Normal file
266
database/perl/vendor/lib/Exporter/Tiny/Manual/Exporting.pod
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
=pod
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=for stopwords frobnicate greps regexps
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Exporter::Tiny::Manual::Exporting - creating an exporter using Exporter::Tiny
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<< Read L<Exporter::Tiny::Manual::QuickStart> first! >>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Simple configuration works the same as L<Exporter>; inherit from
|
||||
L<Exporter::Tiny>, and use the C<< @EXPORT >>, C<< @EXPORT_OK >>,
|
||||
and C<< %EXPORT_TAGS >> package variables to list subs to export.
|
||||
|
||||
Unlike Exporter, Exporter::Tiny performs most of its internal duties
|
||||
(including resolution of tag names to sub names, resolution of sub
|
||||
names to coderefs, and installation of coderefs into the target
|
||||
package) as B<method calls>, which means that your module (which is a
|
||||
subclass of Exporter::Tiny) can override them to provide interesting
|
||||
behaviour.
|
||||
|
||||
=head2 Advanced Tag Stuff
|
||||
|
||||
You can define tags using other tags:
|
||||
|
||||
use Exporter::Shiny qw(
|
||||
black white red green blue cyan magenta yellow
|
||||
);
|
||||
|
||||
our %EXPORT_TAGS = (
|
||||
rgb => [qw( red green blue )],
|
||||
cym => [qw( cyan magenta yellow )],
|
||||
cymk => [qw( black :cym )],
|
||||
monochrome => [qw( black white )],
|
||||
all => [qw( :rgb :cymk :monochrome )],
|
||||
);
|
||||
|
||||
B<< CAVEAT: >> If you create a cycle in the tags, this could put
|
||||
Exporter::Tiny into an infinite loop expanding the tags. Don't do that.
|
||||
|
||||
=head2 More on Generators
|
||||
|
||||
Exporter::Tiny has always allowed exported subs to be generated (like
|
||||
L<Sub::Exporter>), but until version 0.025 did not have an especially nice
|
||||
API for it.
|
||||
|
||||
Now, it's easy. If you want to generate a sub C<foo> to export, list it in
|
||||
C<< @EXPORT >> or C<< @EXPORT_OK >> as usual, and then simply give your
|
||||
exporter module a class method called C<< _generate_foo >>.
|
||||
|
||||
push @EXPORT_OK, 'foo';
|
||||
|
||||
sub _generate_foo {
|
||||
my $class = shift;
|
||||
my ($name, $args, $globals) = @_;
|
||||
|
||||
return sub {
|
||||
...;
|
||||
}
|
||||
}
|
||||
|
||||
We showed how to do that in L<Exporter::Tiny::Manual::QuickStart>, but
|
||||
one thing we didn't show was that C<< $globals >> gets passed in there.
|
||||
This is the global options hash, as described in
|
||||
L<Exporter::Tiny::Manual::Importing>. It can often be useful. In
|
||||
particular it will tell you what package the generated sub is destined
|
||||
to be installed into.
|
||||
|
||||
To generate non-code symbols, name your generators like this:
|
||||
|
||||
sub _generateScalar_Foo { ... } # generate a symbol $Foo
|
||||
sub _generateArray_Bar { ... } # generate a symbol @Bar
|
||||
sub _generateHash_Baz { ... } # generate a symbol %Baz
|
||||
|
||||
You can also generate tags:
|
||||
|
||||
my %constants;
|
||||
BEGIN {
|
||||
%constants = (FOO => 1, BAR => 2);
|
||||
}
|
||||
use constant \%constants;
|
||||
|
||||
$EXPORT_TAGS{constants} = sub {
|
||||
my $class = shift;
|
||||
my ($name, $args, $globals) = @_;
|
||||
|
||||
return keys(%constants);
|
||||
};
|
||||
|
||||
=head2 Hooks
|
||||
|
||||
Sometimes as well as exporting stuff, you want to do some setup or
|
||||
something.
|
||||
|
||||
You can define a couple of class methods in your package, and they'll
|
||||
get called at the appropriate time:
|
||||
|
||||
package MyUtils;
|
||||
|
||||
...;
|
||||
|
||||
sub _exporter_validate_opts {
|
||||
my $class = shift;
|
||||
my ($globals) = @_;
|
||||
|
||||
...; # do stuff here
|
||||
|
||||
$class->SUPER::_exporter_validate_opts(@_);
|
||||
}
|
||||
|
||||
sub _exporter_validate_unimport_opts {
|
||||
my $class = shift;
|
||||
my ($globals) = @_;
|
||||
|
||||
...; # do stuff here
|
||||
|
||||
$class->SUPER::_exporter_validate_unimport_opts(@_);
|
||||
}
|
||||
|
||||
The C<< $globals >> variable is that famous global options hash. In
|
||||
particular, C<< $globals->{into} >> is useful because it tells you what
|
||||
package has imported you.
|
||||
|
||||
As you might have guessed, these methods were originally intended to
|
||||
validate the global options hash, but can be used to perform any
|
||||
general duties before the real exporting work is done.
|
||||
|
||||
=head2 Overriding Internals
|
||||
|
||||
An important difference between L<Exporter> and Exporter::Tiny is that
|
||||
the latter calls all its internal functions as I<< class methods >>. This
|
||||
means that your subclass can I<< override them >> to alter their behaviour.
|
||||
|
||||
The following methods are available to be overridden. Despite being named
|
||||
with a leading underscore, they are considered public methods. (The underscore
|
||||
is there to avoid accidentally colliding with any of your own function names.)
|
||||
|
||||
=over
|
||||
|
||||
=item C<< _exporter_validate_opts($globals) >>
|
||||
|
||||
Documented above.
|
||||
|
||||
=item C<< _exporter_validate_unimport_opts($globals) >>
|
||||
|
||||
Documented above.
|
||||
|
||||
=item C<< _exporter_merge_opts($tag_opts, $globals, @exports) >>
|
||||
|
||||
Called to merge options which have been provided for a tag into the
|
||||
options provided for the exports that the tag expanded to.
|
||||
|
||||
=item C<< _exporter_expand_tag($name, $args, $globals) >>
|
||||
|
||||
This method is called to expand an import tag (e.g. C<< ":constants" >>).
|
||||
It is passed the tag name (minus the leading ":"), an optional hashref
|
||||
of options (like C<< { -prefix => "foo_" } >>), and the global options
|
||||
hashref.
|
||||
|
||||
It is expected to return a list of ($name, $args) arrayref pairs. These
|
||||
names can be sub names to export, or further tag names (which must have
|
||||
their ":"). If returning tag names, be careful to avoid creating a tag
|
||||
expansion loop!
|
||||
|
||||
The default implementation uses C<< %EXPORT_TAGS >> to expand tags, and
|
||||
provides fallbacks for the C<< :default >> and C<< :all >> tags.
|
||||
|
||||
=item C<< _exporter_expand_regexp($regexp, $args, $globals) >>
|
||||
|
||||
Like C<_exporter_expand_regexp>, but given a regexp-like string instead
|
||||
of a tag name.
|
||||
|
||||
The default implementation greps through C<< @EXPORT_OK >> for imports,
|
||||
and the list of already-imported functions for exports.
|
||||
|
||||
=item C<< _exporter_expand_sub($name, $args, $globals) >>
|
||||
|
||||
This method is called to translate a sub name to a hash of name => coderef
|
||||
pairs for exporting to the caller. In general, this would just be a hash with
|
||||
one key and one value, but, for example, L<Type::Library> overrides this
|
||||
method so that C<< "+Foo" >> gets expanded to:
|
||||
|
||||
(
|
||||
Foo => sub { $type },
|
||||
is_Foo => sub { $type->check(@_) },
|
||||
to_Foo => sub { $type->assert_coerce(@_) },
|
||||
assert_Foo => sub { $type->assert_return(@_) },
|
||||
)
|
||||
|
||||
The default implementation checks that the name is allowed to be exported
|
||||
(using the C<_exporter_permitted_regexp> method), gets the coderef using
|
||||
the generator if there is one (or by calling C<< can >> on your exporter
|
||||
otherwise) and calls C<_exporter_fail> if it's unable to generate or
|
||||
retrieve a coderef.
|
||||
|
||||
Despite the name, is also called for non-code symbols.
|
||||
|
||||
=item C<< _exporter_permitted_regexp($globals) >>
|
||||
|
||||
This method is called to retrieve a regexp for validating the names of
|
||||
exportable subs. If a sub doesn't match the regexp, then the default
|
||||
implementation of C<_exporter_expand_sub> will refuse to export it. (Of
|
||||
course, you may override the default C<_exporter_expand_sub>.)
|
||||
|
||||
The default implementation of this method assembles the regexp from
|
||||
C<< @EXPORT >> and C<< @EXPORT_OK >>.
|
||||
|
||||
=item C<< _exporter_fail($name, $args, $globals) >>
|
||||
|
||||
Called by C<_exporter_expand_sub> if it can't find a coderef to export.
|
||||
|
||||
The default implementation just throws an exception. But you could emit
|
||||
a warning instead, or just ignore the failed export.
|
||||
|
||||
If you don't throw an exception then you should be aware that this
|
||||
method is called in list context, and any list it returns will be treated
|
||||
as an C<_exporter_expand_sub>-style hash of names and coderefs for
|
||||
export.
|
||||
|
||||
=item C<< _exporter_install_sub($name, $args, $globals, $coderef) >>
|
||||
|
||||
This method actually installs the exported sub into its new destination.
|
||||
Its return value is ignored.
|
||||
|
||||
The default implementation handles sub renaming (i.e. the C<< -as >>,
|
||||
C<< -prefix >> and C<< -suffix >> functions. This method does a lot of
|
||||
stuff; if you need to override it, it's probably a good idea to just
|
||||
pre-process the arguments and then call the super method rather than
|
||||
trying to handle all of it yourself.
|
||||
|
||||
Despite the name, is also called for non-code symbols.
|
||||
|
||||
=item C<< _exporter_uninstall_sub($name, $args, $globals) >>
|
||||
|
||||
The opposite of C<_exporter_install_sub>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Exporter::Shiny>,
|
||||
L<Exporter::Tiny>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
|
||||
|
||||
=head1 COPYRIGHT AND LICENCE
|
||||
|
||||
This software is copyright (c) 2013-2014, 2017 by Toby Inkster.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=head1 DISCLAIMER OF WARRANTIES
|
||||
|
||||
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
253
database/perl/vendor/lib/Exporter/Tiny/Manual/Importing.pod
vendored
Normal file
253
database/perl/vendor/lib/Exporter/Tiny/Manual/Importing.pod
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
=pod
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=for stopwords frobnicate greps regexps
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Exporter::Tiny::Manual::Importing - importing from Exporter::Tiny-based modules
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
For the purposes of this discussion we'll assume we have a module called
|
||||
C<< MyUtils >> which exports functions called C<frobnicate>, C<red>,
|
||||
C<blue>, and C<green>. It has a tag set up called C<:colours> which
|
||||
corresponds to C<red>, C<blue>, and C<green>.
|
||||
|
||||
Many of these tricks may seem familiar from L<Sub::Exporter>. That is
|
||||
intentional. Exporter::Tiny doesn't attempt to provide every feature of
|
||||
Sub::Exporter, but where it does it usually uses a fairly similar API.
|
||||
|
||||
=head2 Basic importing
|
||||
|
||||
It's easy to import a single function from a module:
|
||||
|
||||
use MyUtils "frobnicate";
|
||||
|
||||
Or a list of functions:
|
||||
|
||||
use MyUtils "red", "green";
|
||||
|
||||
Perl's C<< qw() >> shorthand for a list of words is pretty useful:
|
||||
|
||||
use MyUtils qw( red green );
|
||||
|
||||
If the module defines tags, you can import them like this:
|
||||
|
||||
use MyUtils qw( :colours );
|
||||
|
||||
Or with a hyphen instead of a colon:
|
||||
|
||||
use MyUtils qw( -colours );
|
||||
|
||||
Hyphens are good because Perl will autoquote a bareword that follows
|
||||
them:
|
||||
|
||||
use MyUtils -colours;
|
||||
|
||||
And it's possible to mix function names and tags in the same list:
|
||||
|
||||
use MyUtils qw( frobnicate :colours );
|
||||
|
||||
=head2 Renaming imported functions
|
||||
|
||||
It's possible to rename a function you're importing:
|
||||
|
||||
use MyUtils "frobnicate" => { -as => "frob" };
|
||||
|
||||
Or you can apply a prefix and/or suffix. The following imports the
|
||||
function and calls it C<my_frobinate_thing>.
|
||||
|
||||
use MyUtils "frobnicate" => { -prefix => "my_", -suffix => "_thing" };
|
||||
|
||||
You can apply a prefix/suffix to B<all> functions you import by
|
||||
placing the hashref B<first> in the import list. (This first hashref
|
||||
is referred to as the global options hash, and can do some special
|
||||
things.)
|
||||
|
||||
use MyUtils { prefix => "my_" }, "frobnicate";
|
||||
|
||||
Did you notice that we used C<< -prefix >> and C<< -suffix >> in the
|
||||
normal options hash, but C<< prefix >> and C<< suffix >> (no hyphen)
|
||||
in the global options hash? That's a common pattern with this module.
|
||||
|
||||
You can import the same function multiple times with different names:
|
||||
|
||||
use MyUtils
|
||||
"frobnicate" => { -as => "frob" },
|
||||
"frobnicate" => { -as => "frbnct" };
|
||||
|
||||
Tags can take the C<< -prefix >> and C<< -suffix >> options too. The
|
||||
following imports C<colour_red>, C<colour_green>, and C<colour_blue>:
|
||||
|
||||
use MyUtils -colours => { -prefix => "colour_" };
|
||||
|
||||
You can also set C<< -as >> to be a coderef to generate a function
|
||||
name. This imports functions called C<RED>, C<GREEN>, and C<BLUE>:
|
||||
|
||||
use MyUtils -colours => { -as => sub { uc($_[0]) } };
|
||||
|
||||
Note that it doesn't make sense to use C<< -as >> with a tag unless
|
||||
you're doing this coderef thing. Coderef C<< as >> also works in the
|
||||
global options hash.
|
||||
|
||||
=head2 DO NOT WANT!
|
||||
|
||||
Sometimes you want to supply a list of functions you B<< don't >> want
|
||||
to import. To do that, prefix the function with a bang. This imports
|
||||
everything except "frobnicate":
|
||||
|
||||
use MyUtils qw( -all !frobnicate );
|
||||
|
||||
You can add the bang prefix to tags too. This will import everything
|
||||
except the colours.
|
||||
|
||||
use MyUtils qw( -all !:colours );
|
||||
|
||||
Negated imports always "win", so the following will not import
|
||||
"frobnicate", no matter how many times you repeat it...
|
||||
|
||||
use MyUtils qw( !frobnicate frobnicate frobnicate frobnicate );
|
||||
|
||||
=head2 Importing by regexp
|
||||
|
||||
Here's how you could import all functions beginning with an "f":
|
||||
|
||||
use MyUtils qw( /^F/i );
|
||||
|
||||
Or import everything except functions beginning with a "z":
|
||||
|
||||
use MyUtils qw( -all !/^Z/i );
|
||||
|
||||
Note that regexps are always supplied as I<strings> starting with
|
||||
C<< "/" >>, and not as quoted regexp references (C<< qr/.../ >>).
|
||||
|
||||
=head2 Import functions into another package
|
||||
|
||||
Occasionally you need to import functions not into your own package,
|
||||
but into a different package. You can do that like this:
|
||||
|
||||
use MyUtils { into => "OtherPkg" }, "frobnicate";
|
||||
|
||||
OtherPkg::frobincate(...);
|
||||
|
||||
However, L<Import::Into> will probably provide you with a better
|
||||
approach which doesn't just work with Exporter::Tiny, but B<all>
|
||||
exporters.
|
||||
|
||||
=head2 Lexical subs
|
||||
|
||||
Often you want to make use of an exported function, but don't want
|
||||
it to "pollute" your namespace.
|
||||
|
||||
There is this L<Sub::Exporter::Lexical> thing that was designed as a
|
||||
plugin for L<Sub::Exporter>, but Exporter::Tiny's API is close enough
|
||||
that it will work. Do you remember that global options hash? Just
|
||||
use that to tell Exporter::Tiny to use an alternative sub installer.
|
||||
|
||||
{
|
||||
use Sub::Exporter::Lexical lexical_installer => { -as => "lex" };
|
||||
use MyUtils { installer => lex }, "frobnicate";
|
||||
|
||||
frobnicate(...); # ok
|
||||
}
|
||||
|
||||
frobnicate(...); # not ok
|
||||
|
||||
Another way to do lexical functions is to import a function into a
|
||||
scalar variable:
|
||||
|
||||
my $func;
|
||||
use MyUtils "frobnicate" => { -as => \$func };
|
||||
|
||||
$func->(...);
|
||||
|
||||
You can even provide a hashref to put all imported functions into as
|
||||
part of that global options hash I mentioned earlier.
|
||||
|
||||
my %funcs;
|
||||
use MyUtils { into => \%funcs }, "frobnicate";
|
||||
|
||||
$funcs{frobnicate}->(...);
|
||||
|
||||
=head2 Unimporting
|
||||
|
||||
You can unimport the functions that MyUtils added to your namespace:
|
||||
|
||||
no MyUtils;
|
||||
|
||||
Or just specific ones:
|
||||
|
||||
no MyUtils qw(frobnicate);
|
||||
|
||||
If you renamed a function when you imported it, you should unimport by
|
||||
the new name:
|
||||
|
||||
use MyUtils frobnicate => { -as => "frob" };
|
||||
...;
|
||||
no MyUtils "frob";
|
||||
|
||||
Unimporting using tags and regexps should mostly do what you want.
|
||||
|
||||
=head1 DIAGNOSTICS
|
||||
|
||||
=over
|
||||
|
||||
=item B<< Overwriting existing sub '%s::%s' with sub '%s' exported by %s >>
|
||||
|
||||
A warning issued if Exporter::Tiny is asked to export a symbol which
|
||||
will result in an existing sub being overwritten. This warning can be
|
||||
suppressed using either of the following:
|
||||
|
||||
use MyUtils { replace => 1 }, "frobnicate";
|
||||
use MyUtils "frobnicate" => { -replace => 1 };
|
||||
|
||||
Or can be upgraded to a fatal error:
|
||||
|
||||
use MyUtils { replace => "die" }, "frobnicate";
|
||||
use MyUtils "frobnicate" => { -replace => "die" };
|
||||
|
||||
=item B<< Refusing to overwrite existing sub '%s::%s' with sub '%s' exported by %s >>
|
||||
|
||||
The fatal version of the above warning.
|
||||
|
||||
=item B<< Could not find sub '%s' exported by %s >>
|
||||
|
||||
You requested to import a sub which the package does not provide.
|
||||
|
||||
=item B<< Cannot provide an -as option for tags >>
|
||||
|
||||
Because a tag may provide more than one function, it does not make sense
|
||||
to request a single name for it. Instead use C<< -prefix >> or C<< -suffix >>.
|
||||
|
||||
=item B<< Passing options to unimport '%s' makes no sense >>
|
||||
|
||||
When you import a sub, it occasionally makes sense to pass some options
|
||||
for it. However, when unimporting, options do nothing, so this warning
|
||||
is issued.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Exporter::Shiny>,
|
||||
L<Exporter::Tiny>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
|
||||
|
||||
=head1 COPYRIGHT AND LICENCE
|
||||
|
||||
This software is copyright (c) 2013-2014, 2017 by Toby Inkster.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=head1 DISCLAIMER OF WARRANTIES
|
||||
|
||||
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
195
database/perl/vendor/lib/Exporter/Tiny/Manual/QuickStart.pod
vendored
Normal file
195
database/perl/vendor/lib/Exporter/Tiny/Manual/QuickStart.pod
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
=pod
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=for stopwords frobnicate greps regexps
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Exporter::Tiny::Manual::QuickStart - the quickest way to get up and running with Exporter::Tiny
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package MyUtils;
|
||||
|
||||
use Exporter::Shiny qw( frobnicate );
|
||||
|
||||
sub frobnicate {
|
||||
...; # your code here
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
Now people can use your module like this:
|
||||
|
||||
use MyUtils "frobnicate";
|
||||
|
||||
frobnicate(42);
|
||||
|
||||
Or like this:
|
||||
|
||||
use MyUtils "frobnicate" => { -as => "frob" };
|
||||
|
||||
frob(42);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
See the synopsis. Yes, it's that simple.
|
||||
|
||||
=head2 Next steps
|
||||
|
||||
=head3 Default exports
|
||||
|
||||
Note that the module in the synopsis doesn't export anything by default.
|
||||
If people load C<MyUtils> like this:
|
||||
|
||||
use MyUtils;
|
||||
|
||||
Then they haven't imported any functions. You can specify a default set
|
||||
of functions to be exported like this:
|
||||
|
||||
package MyUtils;
|
||||
|
||||
use Exporter::Shiny qw( frobnicate );
|
||||
|
||||
our @EXPORT = qw( frobnicate );
|
||||
|
||||
sub frobnicate { ... }
|
||||
|
||||
1;
|
||||
|
||||
Or, if you want to be a superstar rock god:
|
||||
|
||||
package MyUtils;
|
||||
|
||||
use Exporter::Shiny our @EXPORT = qw( frobnicate );
|
||||
|
||||
sub frobnicate { ... }
|
||||
|
||||
1;
|
||||
|
||||
=head3 Tags
|
||||
|
||||
You can provide tags for people to use:
|
||||
|
||||
package MyUtils;
|
||||
|
||||
use Exporter::Shiny qw( frobnicate red green blue );
|
||||
|
||||
our %EXPORT_TAGS = (
|
||||
utils => [qw/ frobnicate /],
|
||||
colours => [qw/ red green blue /],
|
||||
);
|
||||
|
||||
sub frobnicate { ... }
|
||||
sub red { ... }
|
||||
sub green { ... }
|
||||
sub blue { ... }
|
||||
|
||||
1;
|
||||
|
||||
And people can now import your functions like this:
|
||||
|
||||
use MyUtils ":colours";
|
||||
|
||||
Or this:
|
||||
|
||||
use MyUtils "-colours";
|
||||
|
||||
Or take advantage of the fact that Perl magically quotes barewords
|
||||
preceded by a hyphen:
|
||||
|
||||
use MyUtils -colours;
|
||||
|
||||
Two tags are automatically defined for you: C<< -default >> (which is
|
||||
just the same as C<< @EXPORT >>) and C<< -all >> (which is the union of
|
||||
C<< @EXPORT >> and C<< @EXPORT_OK >>). If you don't like them, then you
|
||||
can override them:
|
||||
|
||||
our %EXPORT_TAGS = (
|
||||
default => \@some_other_stuff,
|
||||
all => \@more_stuff,
|
||||
);
|
||||
|
||||
=head3 Generators
|
||||
|
||||
Exporting normally just works by copying a sub from your package into
|
||||
your caller's package. But sometimes it's useful instead to generate
|
||||
a I<custom> sub to insert into your caller's package. This is pretty
|
||||
easy to do.
|
||||
|
||||
package MyUtils;
|
||||
|
||||
use Exporter::Shiny qw( frobnicate );
|
||||
|
||||
sub _generate_frobnicate {
|
||||
my $me = shift;
|
||||
my $caller = caller;
|
||||
my ($name, $args) = @_;
|
||||
|
||||
return sub {
|
||||
...; # your code here
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
The parameter C<< $me >> here is a string containing the package name
|
||||
which is being imported from; C<< $caller >> is the destination package;
|
||||
C<< $name >> is the name of the sub (in this case "frobnicate"); and
|
||||
C<< $args >> is a hashref of custom arguments for this function.
|
||||
|
||||
# The hashref { foo => 42 } is $args above.
|
||||
#
|
||||
use MyUtils "frobnicate" => { foo => 42 };
|
||||
|
||||
=head2 Avoiding Exporter::Shiny
|
||||
|
||||
Exporter::Shiny is a tiny shim around Exporter::Tiny. It should mostly
|
||||
do what you want, but you may sometimes prefer to use Exporter::Tiny
|
||||
directly.
|
||||
|
||||
The example in the synopsis could have been written as:
|
||||
|
||||
package MyUtils;
|
||||
|
||||
use parent "Exporter::Tiny";
|
||||
our @EXPORT_OK = qw( frobnicate );
|
||||
|
||||
sub frobnicate {
|
||||
...; # your code here
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
What Exporter::Shiny does is mostly just to set C<< @EXPORT_OK >> for
|
||||
you and set up inheritance from the base class (Exporter::Tiny).
|
||||
|
||||
Exporter::Shiny also sets C<< $INC{'MyUtils.pm} >> for you, which in
|
||||
usually makes little difference, but is useful in some edge cases.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Exporter::Shiny>,
|
||||
L<Exporter::Tiny>.
|
||||
|
||||
For more advanced information, see
|
||||
L<Exporter::Tiny::Manual::Exporting>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
|
||||
|
||||
=head1 COPYRIGHT AND LICENCE
|
||||
|
||||
This software is copyright (c) 2013-2014, 2017 by Toby Inkster.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=head1 DISCLAIMER OF WARRANTIES
|
||||
|
||||
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Reference in New Issue
Block a user