File Coverage

blib/lib/Exporter/Declare.pm
Criterion Covered Total %
statement 110 121 90.9
branch 27 36 75.0
condition 11 19 57.8
subroutine 30 31 96.7
pod 11 12 91.6
total 189 219 86.3


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