/usr/share/perl5/Exporter/Declare.pm is in libexporter-declare-perl 0.114-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | package Exporter::Declare;
use strict;
use warnings;
use Carp qw/croak/;
use Scalar::Util qw/reftype/;
use aliased 'Exporter::Declare::Meta';
use aliased 'Exporter::Declare::Specs';
use aliased 'Exporter::Declare::Export::Sub';
use aliased 'Exporter::Declare::Export::Variable';
use aliased 'Exporter::Declare::Export::Generator';
BEGIN { Meta->new(__PACKAGE__) }
our $VERSION = '0.114';
our @CARP_NOT = qw/
Exporter::Declare
Exporter::Declare::Specs
Exporter::Declare::Meta
Exporter::Declare::Magic
/;
default_exports(
qw/
import
exports
default_exports
import_options
import_arguments
export_tag
export
gen_export
default_export
gen_default_export
/
);
exports(
qw/
reexport
export_to
/
);
export_tag(
magic => qw/
!export
!gen_export
!default_export
!gen_default_export
/
);
sub import {
my $class = shift;
my $caller = caller;
$class->alter_import_args( $caller, \@_ )
if $class->can('alter_import_args');
my $specs = _parse_specs( $class, @_ );
$class->before_import( $caller, $specs )
if $class->can('before_import');
$specs->export($caller);
$class->after_import( $caller, $specs )
if $class->can('after_import');
}
sub after_import {
my $class = shift;
my ( $caller, $specs ) = @_;
Meta->new($caller);
return unless my $args = $specs->config->{'magic'};
$args = ['-default'] unless ref $args && ref $args eq 'ARRAY';
croak "Exporter::Declare::Magic must be installed seperately for -magic to work"
unless eval { require Exporter::Declare::Magic };
warn "Exporter::Declare -magic is deprecated. Please use Exporter::Declare::Magic directly";
export_to( 'Exporter::Declare::Magic', $caller, @$args );
}
sub _parse_specs {
my $class = _find_export_class( \@_ );
my (@args) = @_;
# XXX This is ugly!
unshift @args => '-default'
if $class eq __PACKAGE__
&& grep { $_ eq '-magic' } @args;
return Specs->new( $class, @args );
}
sub export_to {
my $class = _find_export_class( \@_ );
my ( $dest, @args ) = @_;
my $specs = _parse_specs( $class, @args );
$specs->export($dest);
return $specs;
}
sub export_tag {
my $class = _find_export_class( \@_ );
my ( $tag, @list ) = @_;
$class->export_meta->export_tags_push( $tag, @list );
}
sub exports {
my $class = _find_export_class( \@_ );
my $meta = $class->export_meta;
_export( $class, undef, $_ ) for @_;
$meta->export_tags_get('all');
}
sub default_exports {
my $class = _find_export_class( \@_ );
my $meta = $class->export_meta;
$meta->export_tags_push( 'default', _export( $class, undef, $_ ) ) for @_;
$meta->export_tags_get('default');
}
sub export {
my $class = _find_export_class( \@_ );
_export( $class, undef, @_ );
}
sub gen_export {
my $class = _find_export_class( \@_ );
_export( $class, Generator(), @_ );
}
sub default_export {
my $class = _find_export_class( \@_ );
my $meta = $class->export_meta;
$meta->export_tags_push( 'default', _export( $class, undef, @_ ) );
}
sub gen_default_export {
my $class = _find_export_class( \@_ );
my $meta = $class->export_meta;
$meta->export_tags_push( 'default', _export( $class, Generator(), @_ ) );
}
sub import_options {
my $class = _find_export_class( \@_ );
my $meta = $class->export_meta;
$meta->options_add($_) for @_;
}
sub import_arguments {
my $class = _find_export_class( \@_ );
my $meta = $class->export_meta;
$meta->arguments_add($_) for @_;
}
sub _parse_export_params {
my ( $class, $expclass, $name, @param ) = @_;
my $ref = ref( $param[-1] ) ? pop(@param) : undef;
my $meta = $class->export_meta;
( $ref, $name ) = $meta->get_ref_from_package($name)
unless $ref;
( my $type, $name ) = ( $name =~ m/^([\$\@\&\%]?)(.*)$/ );
$type = "" if $type eq '&';
my $fullname = "$type$name";
return (
class => $class,
export_class => $expclass || undef,
name => $name,
ref => $ref,
type => $type || "",
fullname => $fullname,
args => \@param,
);
}
sub _export {
_add_export( _parse_export_params(@_) );
}
sub _add_export {
my %params = @_;
my $meta = $params{class}->export_meta;
$params{export_class} ||=
reftype( $params{ref} ) eq 'CODE'
? Sub()
: Variable();
$params{export_class}->new(
$params{ref},
exported_by => $params{class},
(
$params{type} ? ( type => 'variable' )
: ( type => 'sub' )
),
(
$params{extra_exporter_props} ? %{$params{extra_exporter_props}}
: ()
),
);
$meta->exports_add( $params{fullname}, $params{ref} );
return $params{fullname};
}
sub _is_exporter_class {
my ($name) = @_;
return 0 unless $name;
# This is to work around a bug in older versions of UNIVERSAL::can which
# would issue a warning about $name->can() when $name was not a valid
# package.
# This will first verify that $name is a namespace, if not it will return false.
# If the namespace defines 'export_meta' we know it is an exporter.
# If there is no @ISA array in the namespace we simply return false,
# otherwise we fall back to $name->can().
{
no strict 'refs';
no warnings 'once';
return 0 unless keys %{"$name\::"};
return 1 if defined *{"$name\::export_meta"}{CODE};
return 0 unless @{"$name\::ISA"};
}
return eval { $name->can('export_meta'); 1 };
}
sub _find_export_class {
my $args = shift;
return shift(@$args)
if @$args && _is_exporter_class(@$args);
return caller(1);
}
sub reexport {
my $from = pop;
my $class = shift || caller;
$class->export_meta->reexport($from);
}
1;
=head1 NAME
Exporter::Declare - Exporting done right
=head1 DESCRIPTION
Exporter::Declare is a meta-driven exporting tool. Exporter::Declare tries to
adopt all the good features of other exporting tools, while throwing away
horrible interfaces. Exporter::Declare also provides hooks that allow you to add
options and arguments for import. Finally, Exporter::Declare's meta-driven
system allows for top-notch introspection.
=head1 FEATURES
=over 4
=item Declarative exporting (like L<Moose> for exporting)
=item Meta-driven for introspection
=item Customizable import() method
=item Export groups (tags)
=item Export generators for subs and variables
=item Clear and concise OO API
=item Exports are blessed, allowing for more introspection
=item Import syntax based off of L<Sub::Exporter>
=item Packages export aliases
=back
=head1 SYNOPSIS
=head2 EXPORTER
package Some::Exporter;
use Exporter::Declare;
default_exports qw/ do_the_thing /;
exports qw/ subA subB $SCALAR @ARRAY %HASH /;
# Create a couple tags (import lists)
export_tag subs => qw/ subA subB do_the_thing /;
export_tag vars => qw/ $SCALAR @ARRAY %HASH /;
# These are simple boolean options, pass '-optionA' to enable it.
import_options qw/ optionA optionB /;
# These are options which slurp in the next argument as their value, pass
# '-optionC' => 'foo' to give it a value.
import_arguments qw/ optionC optionD /;
export anon_export => sub { ... };
export '@anon_var' => [...];
default_export a_default => sub { 'default!' }
our $X = "x";
default_export '$X';
my $iterator = 'a';
gen_export unique_class_id => sub {
my $current = $iterator++;
return sub { $current };
};
gen_default_export '$my_letter' => sub {
my $letter = $iterator++;
return \$letter;
};
# You can create a function to mangle the arguments before they are
# parsed into a Exporter::Declare::Spec object.
sub alter_import_args {
my ($class, $importer, $args) = @_;
# fiddle with args before importing routines are called
@$args = grep { !/^skip_/ } @$args
}
# There is no need to fiddle with import() or do any wrapping.
# the $specs data structure means you generally do not need to parse
# arguments yourself (but you can if you want using alter_import_args())
# Change the spec object before export occurs
sub before_import {
my $class = shift;
my ( $importer, $specs ) = @_;
if ($specs->config->{optionA}) {
# Modify $spec attributes accordingly
}
}
# Use spec object after export occurs
sub after_import {
my $class = shift;
my ( $importer, $specs ) = @_;
do_option_a() if $specs->config->{optionA};
do_option_c( $specs->config->{optionC} )
if $specs->config->{optionC};
print "-subs tag was used\n"
if $specs->config->{subs};
print "exported 'subA'\n"
if $specs->exports->{subA};
}
...
=head2 IMPORTER
package Some::Importer;
use Some::Exporter qw/ subA $SCALAR !%HASH /,
-default => { -prefix => 'my_' },
qw/ -optionA !-optionB /,
subB => { -as => 'sub_b' };
subA();
print $SCALAR;
sub_b();
my_do_the_thing();
...
=head1 IMPORT INTERFACE
Importing from a package that uses Exporter::Declare will be familiar to anyone
who has imported from modules before. Arguments are all assumed to be export
names, unless prefixed with C<-> or C<:> In which case they may be a tag or an
option. Exports without a sigil are assumed to be code exports, variable
exports must be listed with their sigil.
Items prefixed with the C<!> symbol are forcefully excluded, regardless of any
listed item that may normally include them. Tags can also be excluded, this
will effectively exclude everything in the tag.
Tags are simply lists of exports, the exporting class may define any number of
tags. Exporter::Declare also has the concept of options, they have the same
syntax as tags. Options may be boolean or argument based. Boolean options are
actually 3 value, undef, false C<!>, or true. Argument based options will grab
the next value in the arguments list as their own, regardless of what type of
value it is.
When you use the module, or call import(), all the arguments are transformed
into an L<Exporter::Declare::Specs> object. Arguments are parsed for you into a
list of imports, and a configuration hash in which tags/options are keys. Tags
are listed in the config hash as true, false, or undef depending on if they
were included, negated, or unlisted. Boolean options will be treated in the
same way as tags. Options that take arguments will have the argument as their
value.
=head2 SELECTING ITEMS TO IMPORT
Exports can be subs, or package variables (scalar, hash, array). For subs
simply ask for the sub by name, you may optionally prefix the subs name with
the sub sigil C<&>. For variables list the variable name along with its sigil
C<$, %, or @>.
use Some::Exporter qw/ somesub $somescalar %somehash @somearray /;
=head2 TAGS
Every exporter automatically has the following 3 tags, in addition they may
define any number of custom tags. Tags can be specified by their name prefixed
by either C<-> or C<:>.
=over 4
=item -all
This tag may be used to import everything the exporter provides.
=item -default
This tag is used to import the default items exported. This will be used when
no argument is provided to import.
=item -alias
Every package has an alias that it can export. This is the last segment of the
packages namespace. IE C<My::Long::Package::Name::Foo> could export the C<Foo()>
function. These alias functions simply return the full package name as a
string, in this case C<'My::Long::Package::Name::Foo'>. This is similar to
L<aliased>.
The -alias tag is a shortcut so that you do not need to think about what the
alias name would be when adding it to the import arguments.
use My::Long::Package::Name::Foo -alias;
my $foo = Foo()->new(...);
=back
=head2 RENAMING IMPORTED ITEMS
You can prefix, suffix, or completely rename the items you import. Whenever an
item is followed by a hash in the import list, that hash will be used for
configuration. Configuration items always start with a dash C<->.
The 3 available configuration options that effect import names are C<-prefix>,
C<-suffix>, and C<-as>. If C<-as> is seen it will be used as is. If prefix or
suffix are seen they will be attached to the original name (unless -as is
present in which case they are ignored).
use Some::Exporter subA => { -as => 'DoThing' },
subB => { -prefix => 'my_', -suffix => '_ok' };
The example above will import C<subA()> under the name C<DoThing()>. It will
also import C<subB()> under the name C<my_subB_ok()>.
You may als specify a prefix and/or suffix for tags. The following example will
import all the default exports with 'my_' prefixed to each name.
use Some::Exporter -default => { -prefix => 'my_' };
=head2 OPTIONS
Some exporters will recognise options. Options look just like tags, and are
specified the same way. What options do, and how they effect things is
exporter-dependant.
use Some::Exporter qw/ -optionA -optionB /;
=head2 ARGUMENTS
Some options require an argument. These options are just like other
tags/options except that the next item in the argument list is slurped in as
the option value.
use Some::Exporter -ArgOption => 'Value, not an export',
-ArgTakesHash => { ... };
Once again available options are exporter specific.
=head2 PROVIDING ARGUMENTS FOR GENERATED ITEMS
Some items are generated at import time. These items may accept arguments.
There are 3 ways to provide arguments, and they may all be mixed (though that
is not recommended).
As a hash
use Some::Exporter generated => { key => 'val', ... };
As an array
use Some::Exporter generated => [ 'Arg1', 'Arg2', ... ];
As an array in a config hash
use Some::Exporter generated => { -as => 'my_gen', -args => [ 'arg1', ... ]};
You can use all three at once, but this is really a bad idea, documented for completeness:
use Some::Exporter generated => { -as => 'my_gen, key => 'value', -args => [ 'arg1', 'arg2' ]}
generated => [ 'arg3', 'arg4' ];
The example above will work fine, all the arguments will make it into the
generator. The only valid reason for this to work is that you may provide
arguments such as C<-prefix> to a tag that brings in generator(), while also
desiring to give arguments to generator() independently.
=head1 PRIMARY EXPORT API
With the exception of import(), all the following work equally well as
functions or class methods.
=over 4
=item import( @args )
The import() class method. This turns the @args list into an
L<Exporter::Declare::Specs> object.
=item exports( @add_items )
Add items to be exported.
=item @list = exports()
Retrieve list of exports.
=item default_exports( @add_items )
Add items to be exported, and add them to the -default tag.
=item @list = default_exports()
List of exports in the -default tag
=item import_options(@add_items)
Specify boolean options that should be accepted at import time.
=item import_arguments(@add_items)
Specify options that should be accepted at import that take arguments.
=item export_tag( $name, @add_items );
Define an export tag, or add items to an existing tag.
=back
=head1 EXTENDED EXPORT API
These all work fine in function or method form, however the syntax sugar will
only work in function form.
=over 4
=item reexport( $package )
Make this exporter inherit all the exports and tags of $package. Works for
Exporter::Declare or Exporter.pm based exporters. Re-Exporting of
L<Sub::Exporter> based classes is not currently supported.
=item export_to( $package, @args )
Export to the specified class.
=item export( $name )
=item export( $name, $ref )
export is a keyword that lets you export any 1 item at a time. The item can be
exported by name, or name + ref. When a ref is provided, the export is created,
but there is no corresponding variable/sub in the packages namespace.
=item default_export( $name )
=item default_export( $name, $ref )
=item gen_export( $name )
=item gen_export( $name, $ref )
=item gen_default_export( $name )
=item gen_default_export( $name, $ref )
These all act just like export(), except that they add subrefs as generators,
and/or add exports to the -default tag.
=back
=head1 MAGIC
Please use L<Exporter::Declare::Magic> directly from now on.
=head2 DEPRECATED USAGE OF MAGIC
use Exporter::Declare '-magic';
This adds L<Devel::Declare> magic to several functions. It also allows you to
easily create or use parsers on your own exports. See
L<Exporter::Declare::Magic> for more details.
You can also provide import arguments to L<Devel::Declare::Magic>
# Arguments to -magic must be in an arrayref, not a hashref.
use Exporter::Declare -magic => [ '-default', '!export', -prefix => 'magic_' ];
=head1 INTERNAL API
Exporter/Declare.pm does not have much logic to speak of. Rather
Exporter::Declare is sugar on top of class meta data stored in
L<Exporter::Declare::Meta> objects. Arguments are parsed via
L<Exporter::Declare::Specs>, and also turned into objects. Even exports are
blessed references to the exported item itself, and handle the injection on
their own (See L<Exporter::Declare::Export>).
=head1 META CLASS
All exporters have a meta class, the only way to get the meta object is to call
the export_meta() method on the class/object that is an exporter. Any class
that uses Exporter::Declare gets this method, and a meta-object.
=head1 AUTHORS
Chad Granum L<exodist7@gmail.com>
=head1 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.
|