Exporter.pm
Go to the documentation of this file.
00001 # Original package Sub::Exporter downloaded from CPAN on 6/15/2012. This module 00002 # has been modified by Andreas Schuh on 6/15/2012 to make it part of BASIS. 00003 00004 use 5.006; 00005 use strict; 00006 use warnings; 00007 package BASIS::Sub::Exporter; 00008 { 00009 $BASIS::Sub::Exporter::VERSION = '0.984'; 00010 } 00011 # ABSTRACT: a sophisticated exporter for custom-built routines 00012 00013 use Carp (); 00014 use BASIS::Data::OptList 0.100 (); 00015 use BASIS::Params::Util 0.14 (); # _CODELIKE 00016 use BASIS::Sub::Install 0.92 (); 00017 00018 00019 # Given a potential import name, this returns the group name -- if it's got a 00020 # group prefix. 00021 sub _group_name { 00022 my ($name) = @_; 00023 00024 return if (index q{-:}, (substr $name, 0, 1)) == -1; 00025 return substr $name, 1; 00026 } 00027 00028 # \@groups is a canonicalized opt list of exports and groups this returns 00029 # another canonicalized opt list with groups replaced with relevant exports. 00030 # \%seen is groups we've already expanded and can ignore. 00031 # \%merge is merged options from the group we're descending through. 00032 sub _expand_groups { 00033 my ($class, $config, $groups, $collection, $seen, $merge) = @_; 00034 $seen ||= {}; 00035 $merge ||= {}; 00036 my @groups = @$groups; 00037 00038 for my $i (reverse 0 .. $#groups) { 00039 if (my $group_name = _group_name($groups[$i][0])) { 00040 my $seen = { %$seen }; # faux-dynamic scoping 00041 00042 splice @groups, $i, 1, 00043 _expand_group($class, $config, $groups[$i], $collection, $seen, $merge); 00044 } else { 00045 # there's nothing to munge in this export's args 00046 next unless my %merge = %$merge; 00047 00048 # we have things to merge in; do so 00049 my $prefix = (delete $merge{-prefix}) || ''; 00050 my $suffix = (delete $merge{-suffix}) || ''; 00051 00052 if ( 00053 BASIS::Params::Util::_CODELIKE($groups[$i][1]) ## no critic Private 00054 or 00055 BASIS::Params::Util::_SCALAR0($groups[$i][1]) ## no critic Private 00056 ) { 00057 # this entry was build by a group generator 00058 $groups[$i][0] = $prefix . $groups[$i][0] . $suffix; 00059 } else { 00060 my $as 00061 = ref $groups[$i][1]{-as} ? $groups[$i][1]{-as} 00062 : $groups[$i][1]{-as} ? $prefix . $groups[$i][1]{-as} . $suffix 00063 : $prefix . $groups[$i][0] . $suffix; 00064 00065 $groups[$i][1] = { %{ $groups[$i][1] }, %merge, -as => $as }; 00066 } 00067 } 00068 } 00069 00070 return \@groups; 00071 } 00072 00073 # \@group is a name/value pair from an opt list. 00074 sub _expand_group { 00075 my ($class, $config, $group, $collection, $seen, $merge) = @_; 00076 $merge ||= {}; 00077 00078 my ($group_name, $group_arg) = @$group; 00079 $group_name = _group_name($group_name); 00080 00081 Carp::croak qq(group "$group_name" is not exported by the $class module) 00082 unless exists $config->{groups}{$group_name}; 00083 00084 return if $seen->{$group_name}++; 00085 00086 if (ref $group_arg) { 00087 my $prefix = (delete $merge->{-prefix}||'') . ($group_arg->{-prefix}||''); 00088 my $suffix = ($group_arg->{-suffix}||'') . (delete $merge->{-suffix}||''); 00089 $merge = { 00090 %$merge, 00091 %$group_arg, 00092 ($prefix ? (-prefix => $prefix) : ()), 00093 ($suffix ? (-suffix => $suffix) : ()), 00094 }; 00095 } 00096 00097 my $exports = $config->{groups}{$group_name}; 00098 00099 if ( 00100 BASIS::Params::Util::_CODELIKE($exports) ## no critic Private 00101 or 00102 BASIS::Params::Util::_SCALAR0($exports) ## no critic Private 00103 ) { 00104 # I'm not very happy with this code for hiding -prefix and -suffix, but 00105 # it's needed, and I'm not sure, offhand, how to make it better. 00106 # -- rjbs, 2006-12-05 00107 my $group_arg = $merge ? { %$merge } : {}; 00108 delete $group_arg->{-prefix}; 00109 delete $group_arg->{-suffix}; 00110 00111 my $group = BASIS::Params::Util::_CODELIKE($exports) ## no critic Private 00112 ? $exports->($class, $group_name, $group_arg, $collection) 00113 : $class->$$exports($group_name, $group_arg, $collection); 00114 00115 Carp::croak qq(group generator "$group_name" did not return a hashref) 00116 if ref $group ne 'HASH'; 00117 00118 my $stuff = [ map { [ $_ => $group->{$_} ] } keys %$group ]; 00119 return @{ 00120 _expand_groups($class, $config, $stuff, $collection, $seen, $merge) 00121 }; 00122 } else { 00123 $exports 00124 = BASIS::Data::OptList::mkopt($exports, "$group_name exports"); 00125 00126 return @{ 00127 _expand_groups($class, $config, $exports, $collection, $seen, $merge) 00128 }; 00129 } 00130 } 00131 00132 sub _mk_collection_builder { 00133 my ($col, $etc) = @_; 00134 my ($config, $import_args, $class, $into) = @$etc; 00135 00136 my %seen; 00137 sub { 00138 my ($collection) = @_; 00139 my ($name, $value) = @$collection; 00140 00141 Carp::croak "collection $name provided multiple times in import" 00142 if $seen{ $name }++; 00143 00144 if (ref(my $hook = $config->{collectors}{$name})) { 00145 my $arg = { 00146 name => $name, 00147 config => $config, 00148 import_args => $import_args, 00149 class => $class, 00150 into => $into, 00151 }; 00152 00153 my $error_msg = "collection $name failed validation"; 00154 if (BASIS::Params::Util::_SCALAR0($hook)) { ## no critic Private 00155 Carp::croak $error_msg unless $class->$$hook($value, $arg); 00156 } else { 00157 Carp::croak $error_msg unless $hook->($value, $arg); 00158 } 00159 } 00160 00161 $col->{ $name } = $value; 00162 } 00163 } 00164 00165 # Given a config and pre-canonicalized importer args, remove collections from 00166 # the args and return them. 00167 sub _collect_collections { 00168 my ($config, $import_args, $class, $into) = @_; 00169 00170 my @collections 00171 = map { splice @$import_args, $_, 1 } 00172 grep { exists $config->{collectors}{ $import_args->[$_][0] } } 00173 reverse 0 .. $#$import_args; 00174 00175 unshift @collections, [ INIT => {} ] if $config->{collectors}{INIT}; 00176 00177 my $col = {}; 00178 my $builder = _mk_collection_builder($col, \@_); 00179 for my $collection (@collections) { 00180 $builder->($collection) 00181 } 00182 00183 return $col; 00184 } 00185 00186 00187 sub setup_exporter { 00188 my ($config) = @_; 00189 00190 Carp::croak 'into and into_level may not both be supplied to exporter' 00191 if exists $config->{into} and exists $config->{into_level}; 00192 00193 my $as = delete $config->{as} || 'import'; 00194 my $into 00195 = exists $config->{into} ? delete $config->{into} 00196 : exists $config->{into_level} ? caller(delete $config->{into_level}) 00197 : caller(0); 00198 00199 my $import = build_exporter($config); 00200 00201 BASIS::Sub::Install::reinstall_sub({ 00202 code => $import, 00203 into => $into, 00204 as => $as, 00205 }); 00206 } 00207 00208 00209 sub _key_intersection { 00210 my ($x, $y) = @_; 00211 my %seen = map { $_ => 1 } keys %$x; 00212 my @names = grep { $seen{$_} } keys %$y; 00213 } 00214 00215 # Given the config passed to setup_exporter, which contains sugary opt list 00216 # data, rewrite the opt lists into hashes, catch a few kinds of invalid 00217 # configurations, and set up defaults. Since the config is a reference, it's 00218 # rewritten in place. 00219 my %valid_config_key; 00220 BEGIN { 00221 %valid_config_key = 00222 map { $_ => 1 } 00223 qw(as collectors installer generator exports groups into into_level), 00224 qw(exporter), # deprecated 00225 } 00226 00227 sub _assert_collector_names_ok { 00228 my ($collectors) = @_; 00229 00230 for my $reserved_name (grep { /\A[_A-Z]+\z/ } keys %$collectors) { 00231 Carp::croak "unknown reserved collector name: $reserved_name" 00232 if $reserved_name ne 'INIT'; 00233 } 00234 } 00235 00236 sub _rewrite_build_config { 00237 my ($config) = @_; 00238 00239 if (my @keys = grep { not exists $valid_config_key{$_} } keys %$config) { 00240 Carp::croak "unknown options (@keys) passed to BASIS::Sub::Exporter"; 00241 } 00242 00243 Carp::croak q(into and into_level may not both be supplied to exporter) 00244 if exists $config->{into} and exists $config->{into_level}; 00245 00246 # XXX: Remove after deprecation period. 00247 if ($config->{exporter}) { 00248 Carp::cluck "'exporter' argument to build_exporter is deprecated. Use 'installer' instead; the semantics are identical."; 00249 $config->{installer} = delete $config->{exporter}; 00250 } 00251 00252 Carp::croak q(into and into_level may not both be supplied to exporter) 00253 if exists $config->{into} and exists $config->{into_level}; 00254 00255 for (qw(exports collectors)) { 00256 $config->{$_} = BASIS::Data::OptList::mkopt_hash( 00257 $config->{$_}, 00258 $_, 00259 [ 'CODE', 'SCALAR' ], 00260 ); 00261 } 00262 00263 _assert_collector_names_ok($config->{collectors}); 00264 00265 if (my @names = _key_intersection(@$config{qw(exports collectors)})) { 00266 Carp::croak "names (@names) used in both collections and exports"; 00267 } 00268 00269 $config->{groups} = BASIS::Data::OptList::mkopt_hash( 00270 $config->{groups}, 00271 'groups', 00272 [ 00273 'HASH', # standard opt list 00274 'ARRAY', # standard opt list 00275 'CODE', # group generator 00276 'SCALAR', # name of group generation method 00277 ] 00278 ); 00279 00280 # by default, export nothing 00281 $config->{groups}{default} ||= []; 00282 00283 # by default, build an all-inclusive 'all' group 00284 $config->{groups}{all} ||= [ keys %{ $config->{exports} } ]; 00285 00286 $config->{generator} ||= \&default_generator; 00287 $config->{installer} ||= \&default_installer; 00288 } 00289 00290 sub build_exporter { 00291 my ($config) = @_; 00292 00293 _rewrite_build_config($config); 00294 00295 my $import = sub { 00296 my ($class) = shift; 00297 00298 # XXX: clean this up -- rjbs, 2006-03-16 00299 my $special = (ref $_[0]) ? shift(@_) : {}; 00300 Carp::croak q(into and into_level may not both be supplied to exporter) 00301 if exists $special->{into} and exists $special->{into_level}; 00302 00303 if ($special->{exporter}) { 00304 Carp::cluck "'exporter' special import argument is deprecated. Use 'installer' instead; the semantics are identical."; 00305 $special->{installer} = delete $special->{exporter}; 00306 } 00307 00308 my $into 00309 = defined $special->{into} ? delete $special->{into} 00310 : defined $special->{into_level} ? caller(delete $special->{into_level}) 00311 : defined $config->{into} ? $config->{into} 00312 : defined $config->{into_level} ? caller($config->{into_level}) 00313 : caller(0); 00314 00315 my $generator = delete $special->{generator} || $config->{generator}; 00316 my $installer = delete $special->{installer} || $config->{installer}; 00317 00318 # this builds a AOA, where the inner arrays are [ name => value_ref ] 00319 my $import_args = BASIS::Data::OptList::mkopt([ @_ ]); 00320 00321 # is this right? defaults first or collectors first? -- rjbs, 2006-06-24 00322 $import_args = [ [ -default => undef ] ] unless @$import_args; 00323 00324 my $collection = _collect_collections($config, $import_args, $class, $into); 00325 00326 my $to_import = _expand_groups($class, $config, $import_args, $collection); 00327 00328 # now, finally $import_arg is really the "to do" list 00329 _do_import( 00330 { 00331 class => $class, 00332 col => $collection, 00333 config => $config, 00334 into => $into, 00335 generator => $generator, 00336 installer => $installer, 00337 }, 00338 $to_import, 00339 ); 00340 }; 00341 00342 return $import; 00343 } 00344 00345 sub _do_import { 00346 my ($arg, $to_import) = @_; 00347 00348 my @todo; 00349 00350 for my $pair (@$to_import) { 00351 my ($name, $import_arg) = @$pair; 00352 00353 my ($generator, $as); 00354 00355 if ($import_arg and BASIS::Params::Util::_CODELIKE($import_arg)) { ## no critic 00356 # This is the case when a group generator has inserted name/code pairs. 00357 $generator = sub { $import_arg }; 00358 $as = $name; 00359 } else { 00360 $import_arg = { $import_arg ? %$import_arg : () }; 00361 00362 Carp::croak qq("$name" is not exported by the $arg->{class} module) 00363 unless exists $arg->{config}{exports}{$name}; 00364 00365 $generator = $arg->{config}{exports}{$name}; 00366 00367 $as = exists $import_arg->{-as} ? (delete $import_arg->{-as}) : $name; 00368 } 00369 00370 my $code = $arg->{generator}->( 00371 { 00372 class => $arg->{class}, 00373 name => $name, 00374 arg => $import_arg, 00375 col => $arg->{col}, 00376 generator => $generator, 00377 } 00378 ); 00379 00380 push @todo, $as, $code; 00381 } 00382 00383 $arg->{installer}->( 00384 { 00385 class => $arg->{class}, 00386 into => $arg->{into}, 00387 col => $arg->{col}, 00388 }, 00389 \@todo, 00390 ); 00391 } 00392 00393 # Cute idea, possibly for future use: also supply an "unimport" for: 00394 # no Module::Whatever qw(arg arg arg); 00395 # sub _unexport { 00396 # my (undef, undef, undef, undef, undef, $as, $into) = @_; 00397 # 00398 # if (ref $as eq 'SCALAR') { 00399 # undef $$as; 00400 # } elsif (ref $as) { 00401 # Carp::croak "invalid reference type for $as: " . ref $as; 00402 # } else { 00403 # no strict 'refs'; 00404 # delete &{$into . '::' . $as}; 00405 # } 00406 # } 00407 00408 00409 sub default_generator { 00410 my ($arg) = @_; 00411 my ($class, $name, $generator) = @$arg{qw(class name generator)}; 00412 00413 if (not defined $generator) { 00414 my $code = $class->can($name) 00415 or Carp::croak "can't locate exported subroutine $name via $class"; 00416 return $code; 00417 } 00418 00419 # I considered making this "$class->$generator(" but it seems that 00420 # overloading precedence would turn an overloaded-as-code generator object 00421 # into a string before code. -- rjbs, 2006-06-11 00422 return $generator->($class, $name, $arg->{arg}, $arg->{col}) 00423 if BASIS::Params::Util::_CODELIKE($generator); ## no critic Private 00424 00425 # This "must" be a scalar reference, to a generator method name. 00426 # -- rjbs, 2006-12-05 00427 return $class->$$generator($name, $arg->{arg}, $arg->{col}); 00428 } 00429 00430 00431 sub default_installer { 00432 my ($arg, $to_export) = @_; 00433 00434 for (my $i = 0; $i < @$to_export; $i += 2) { 00435 my ($as, $code) = @$to_export[ $i, $i+1 ]; 00436 00437 # Allow as isa ARRAY to push onto an array? 00438 # Allow into isa HASH to install name=>code into hash? 00439 00440 if (ref $as eq 'SCALAR') { 00441 $$as = $code; 00442 } elsif (ref $as) { 00443 Carp::croak "invalid reference type for $as: " . ref $as; 00444 } else { 00445 BASIS::Sub::Install::reinstall_sub({ 00446 code => $code, 00447 into => $arg->{into}, 00448 as => $as 00449 }); 00450 } 00451 } 00452 } 00453 00454 sub default_exporter { 00455 Carp::cluck "default_exporter is deprecated; call default_installer instead; the semantics are identical"; 00456 goto &default_installer; 00457 } 00458 00459 00460 setup_exporter({ 00461 exports => [ 00462 qw(setup_exporter build_exporter), 00463 _import => sub { build_exporter($_[2]) }, 00464 ], 00465 groups => { 00466 all => [ qw(setup_exporter build_export) ], 00467 }, 00468 collectors => { -setup => \&_setup }, 00469 }); 00470 00471 sub _setup { 00472 my ($value, $arg) = @_; 00473 00474 if (ref $value eq 'HASH') { 00475 push @{ $arg->{import_args} }, [ _import => { -as => 'import', %$value } ]; 00476 return 1; 00477 } elsif (ref $value eq 'ARRAY') { 00478 push @{ $arg->{import_args} }, 00479 [ _import => { -as => 'import', exports => $value } ]; 00480 return 1; 00481 } 00482 return; 00483 } 00484 00485 00486 00487 "jn8:32"; # <-- magic true value 00488 00489 __END__ 00490 =pod 00491 00492 =head1 NAME 00493 00494 BASIS::Sub::Exporter - a sophisticated exporter for custom-built routines 00495 00496 =head1 VERSION 00497 00498 version 0.984 00499 00500 =head1 SYNOPSIS 00501 00502 BASIS::Sub::Exporter must be used in two places. First, in an exporting module: 00503 00504 # in the exporting module: 00505 package Text::Tweaker; 00506 use BASIS::Sub::Exporter -setup => { 00507 exports => [ 00508 qw(squish titlecase), # always works the same way 00509 reformat => \&build_reformatter, # generator to build exported function 00510 trim => \&build_trimmer, 00511 indent => \&build_indenter, 00512 ], 00513 collectors => [ 'defaults' ], 00514 }; 00515 00516 Then, in an importing module: 00517 00518 # in the importing module: 00519 use Text::Tweaker 00520 'squish', 00521 indent => { margin => 5 }, 00522 reformat => { width => 79, justify => 'full', -as => 'prettify_text' }, 00523 defaults => { eol => 'CRLF' }; 00524 00525 With this setup, the importing module ends up with three routines: C<squish>, 00526 C<indent>, and C<prettify_text>. The latter two have been built to the 00527 specifications of the importer -- they are not just copies of the code in the 00528 exporting package. 00529 00530 =head1 DESCRIPTION 00531 00532 B<ACHTUNG!> If you're not familiar with Exporter or exporting, read 00533 L<BASIS::Sub::Exporter::Tutorial> first! 00534 00535 =head2 Why Generators? 00536 00537 The biggest benefit of BASIS::Sub::Exporter over existing exporters (including the 00538 ubiquitous Exporter.pm) is its ability to build new coderefs for export, rather 00539 than to simply export code identical to that found in the exporting package. 00540 00541 If your module's consumers get a routine that works like this: 00542 00543 use Data::Analyze qw(analyze); 00544 my $value = analyze($data, $tolerance, $passes); 00545 00546 and they constantly pass only one or two different set of values for the 00547 non-C<$data> arguments, your code can benefit from BASIS::Sub::Exporter. By writing a 00548 simple generator, you can let them do this, instead: 00549 00550 use Data::Analyze 00551 analyze => { tolerance => 0.10, passes => 10, -as => analyze10 }, 00552 analyze => { tolerance => 0.15, passes => 50, -as => analyze50 }; 00553 00554 my $value = analyze10($data); 00555 00556 The generator for that would look something like this: 00557 00558 sub build_analyzer { 00559 my ($class, $name, $arg) = @_; 00560 00561 return sub { 00562 my $data = shift; 00563 my $tolerance = shift || $arg->{tolerance}; 00564 my $passes = shift || $arg->{passes}; 00565 00566 analyze($data, $tolerance, $passes); 00567 } 00568 } 00569 00570 Your module's user now has to do less work to benefit from it -- and remember, 00571 you're often your own user! Investing in customized subroutines is an 00572 investment in future laziness. 00573 00574 This also avoids a common form of ugliness seen in many modules: package-level 00575 configuration. That is, you might have seen something like the above 00576 implemented like so: 00577 00578 use Data::Analyze qw(analyze); 00579 $Data::Analyze::default_tolerance = 0.10; 00580 $Data::Analyze::default_passes = 10; 00581 00582 This might save time, until you have multiple modules using Data::Analyze. 00583 Because there is only one global configuration, they step on each other's toes 00584 and your code begins to have mysterious errors. 00585 00586 Generators can also allow you to export class methods to be called as 00587 subroutines: 00588 00589 package Data::Methodical; 00590 use BASIS::Sub::Exporter -setup => { exports => { some_method => \&_curry_class } }; 00591 00592 sub _curry_class { 00593 my ($class, $name) = @_; 00594 sub { $class->$name(@_); }; 00595 } 00596 00597 Because of the way that exporters and BASIS::Sub::Exporter work, any package that 00598 inherits from Data::Methodical can inherit its exporter and override its 00599 C<some_method>. If a user imports C<some_method> from that package, he'll 00600 receive a subroutine that calls the method on the subclass, rather than on 00601 Data::Methodical itself. 00602 00603 =head2 Other Customizations 00604 00605 Building custom routines with generators isn't the only way that BASIS::Sub::Exporters 00606 allows the importing code to refine its use of the exported routines. They may 00607 also be renamed to avoid naming collisions. 00608 00609 Consider the following code: 00610 00611 # this program determines to which circle of Hell you will be condemned 00612 use Morality qw(sin virtue); # for calculating viciousness 00613 use Math::Trig qw(:all); # for dealing with circles 00614 00615 The programmer has inadvertently imported two C<sin> routines. The solution, 00616 in Exporter.pm-based modules, would be to import only one and then call the 00617 other by its fully-qualified name. Alternately, the importer could write a 00618 routine that did so, or could mess about with typeglobs. 00619 00620 How much easier to write: 00621 00622 # this program determines to which circle of Hell you will be condemned 00623 use Morality qw(virtue), sin => { -as => 'offense' }; 00624 use Math::Trig -all => { -prefix => 'trig_' }; 00625 00626 and to have at one's disposal C<offense> and C<trig_sin> -- not to mention 00627 C<trig_cos> and C<trig_tan>. 00628 00629 =head1 EXPORTER CONFIGURATION 00630 00631 You can configure an exporter for your package by using BASIS::Sub::Exporter like so: 00632 00633 package Tools; 00634 use BASIS::Sub::Exporter 00635 -setup => { exports => [ qw(function1 function2 function3) ] }; 00636 00637 This is the simplest way to use the exporter, and is basically equivalent to 00638 this: 00639 00640 package Tools; 00641 use base qw(Exporter); 00642 our @EXPORT_OK = qw(function1 function2 function2); 00643 00644 Any basic use of BASIS::Sub::Exporter will look like this: 00645 00646 package Tools; 00647 use BASIS::Sub::Exporter -setup => \%config; 00648 00649 The following keys are valid in C<%config>: 00650 00651 exports - a list of routines to provide for exporting; each routine may be 00652 followed by generator 00653 groups - a list of groups to provide for exporting; each must be followed by 00654 either (a) a list of exports, possibly with arguments for each 00655 export, or (b) a generator 00656 00657 collectors - a list of names into which values are collected for use in 00658 routine generation; each name may be followed by a validator 00659 00660 In addition to the basic options above, a few more advanced options may be 00661 passed: 00662 00663 into_level - how far up the caller stack to look for a target (default 0) 00664 into - an explicit target (package) into which to export routines 00665 00666 In other words: BASIS::Sub::Exporter installs a C<import> routine which, when called, 00667 exports routines to the calling namespace. The C<into> and C<into_level> 00668 options change where those exported routines are installed. 00669 00670 generator - a callback used to produce the code that will be installed 00671 default: BASIS::Sub::Exporter::default_generator 00672 00673 installer - a callback used to install the code produced by the generator 00674 default: BASIS::Sub::Exporter::default_installer 00675 00676 For information on how these callbacks are used, see the documentation for 00677 C<L</default_generator>> and C<L</default_installer>>. 00678 00679 =head2 Export Configuration 00680 00681 The C<exports> list may be provided as an array reference or a hash reference. 00682 The list is processed in such a way that the following are equivalent: 00683 00684 { exports => [ qw(foo bar baz), quux => \&quux_generator ] } 00685 00686 { exports => 00687 { foo => undef, bar => undef, baz => undef, quux => \&quux_generator } } 00688 00689 Generators are code that return coderefs. They are called with four 00690 parameters: 00691 00692 $class - the class whose exporter has been called (the exporting class) 00693 $name - the name of the export for which the routine is being build 00694 \%arg - the arguments passed for this export 00695 \%col - the collections for this import 00696 00697 Given the configuration in the L</SYNOPSIS>, the following C<use> statement: 00698 00699 use Text::Tweaker 00700 reformat => { -as => 'make_narrow', width => 33 }, 00701 defaults => { eol => 'CR' }; 00702 00703 would result in the following call to C<&build_reformatter>: 00704 00705 my $code = build_reformatter( 00706 'Text::Tweaker', 00707 'reformat', 00708 { width => 33 }, # note that -as is not passed in 00709 { defaults => { eol => 'CR' } }, 00710 ); 00711 00712 The returned coderef (C<$code>) would then be installed as C<make_narrow> in the 00713 calling package. 00714 00715 Instead of providing a coderef in the configuration, a reference to a method 00716 name may be provided. This method will then be called on the invocant of the 00717 C<import> method. (In this case, we do not pass the C<$class> parameter, as it 00718 would be redundant.) 00719 00720 =head2 Group Configuration 00721 00722 The C<groups> list can be passed in the same forms as C<exports>. Groups must 00723 have values to be meaningful, which may either list exports that make up the 00724 group (optionally with arguments) or may provide a way to build the group. 00725 00726 The simpler case is the first: a group definition is a list of exports. Here's 00727 the example that could go in exporter in the L</SYNOPSIS>. 00728 00729 groups => { 00730 default => [ qw(reformat) ], 00731 shorteners => [ qw(squish trim) ], 00732 email_safe => [ 00733 'indent', 00734 reformat => { -as => 'email_format', width => 72 } 00735 ], 00736 }, 00737 00738 Groups are imported by specifying their name prefixed be either a dash or a 00739 colon. This line of code would import the C<shorteners> group: 00740 00741 use Text::Tweaker qw(-shorteners); 00742 00743 Arguments passed to a group when importing are merged into the groups options 00744 and passed to any relevant generators. Groups can contain other groups, but 00745 looping group structures are ignored. 00746 00747 The other possible value for a group definition, a coderef, allows one 00748 generator to build several exportable routines simultaneously. This is useful 00749 when many routines must share enclosed lexical variables. The coderef must 00750 return a hash reference. The keys will be used as export names and the values 00751 are the subs that will be exported. 00752 00753 This example shows a simple use of the group generator. 00754 00755 package Data::Crypto; 00756 use BASIS::Sub::Exporter -setup => { groups => { cipher => \&build_cipher_group } }; 00757 00758 sub build_cipher_group { 00759 my ($class, $group, $arg) = @_; 00760 my ($encode, $decode) = build_codec($arg->{secret}); 00761 return { cipher => $encode, decipher => $decode }; 00762 } 00763 00764 The C<cipher> and C<decipher> routines are built in a group because they are 00765 built together by code which encloses their secret in their environment. 00766 00767 =head3 Default Groups 00768 00769 If a module that uses BASIS::Sub::Exporter is C<use>d with no arguments, it will try 00770 to export the group named C<default>. If that group has not been specifically 00771 configured, it will be empty, and nothing will happen. 00772 00773 Another group is also created if not defined: C<all>. The C<all> group 00774 contains all the exports from the exports list. 00775 00776 =head2 Collector Configuration 00777 00778 The C<collectors> entry in the exporter configuration gives names which, when 00779 found in the import call, have their values collected and passed to every 00780 generator. 00781 00782 For example, the C<build_analyzer> generator that we saw above could be 00783 rewritten as: 00784 00785 sub build_analyzer { 00786 my ($class, $name, $arg, $col) = @_; 00787 00788 return sub { 00789 my $data = shift; 00790 my $tolerance = shift || $arg->{tolerance} || $col->{defaults}{tolerance}; 00791 my $passes = shift || $arg->{passes} || $col->{defaults}{passes}; 00792 00793 analyze($data, $tolerance, $passes); 00794 } 00795 } 00796 00797 That would allow the import to specify global defaults for his imports: 00798 00799 use Data::Analyze 00800 'analyze', 00801 analyze => { tolerance => 0.10, -as => analyze10 }, 00802 analyze => { tolerance => 0.15, passes => 50, -as => analyze50 }, 00803 defaults => { passes => 10 }; 00804 00805 my $A = analyze10($data); # equivalent to analyze($data, 0.10, 10); 00806 my $C = analyze50($data); # equivalent to analyze($data, 0.15, 10); 00807 my $B = analyze($data, 0.20); # equivalent to analyze($data, 0.20, 10); 00808 00809 If values are provided in the C<collectors> list during exporter setup, they 00810 must be code references, and are used to validate the importer's values. The 00811 validator is called when the collection is found, and if it returns false, an 00812 exception is thrown. We could ensure that no one tries to set a global data 00813 default easily: 00814 00815 collectors => { defaults => sub { return (exists $_[0]->{data}) ? 0 : 1 } } 00816 00817 Collector coderefs can also be used as hooks to perform arbitrary actions 00818 before anything is exported. 00819 00820 When the coderef is called, it is passed the value of the collection and a 00821 hashref containing the following entries: 00822 00823 name - the name of the collector 00824 config - the exporter configuration (hashref) 00825 import_args - the arguments passed to the exporter, sans collections (aref) 00826 class - the package on which the importer was called 00827 into - the package into which exports will be exported 00828 00829 Collectors with all-caps names (that is, made up of underscore or capital A 00830 through Z) are reserved for special use. The only currently implemented 00831 special collector is C<INIT>, whose hook (if present in the exporter 00832 configuration) is always run before any other hook. 00833 00834 =head1 CALLING THE EXPORTER 00835 00836 Arguments to the exporter (that is, the arguments after the module name in a 00837 C<use> statement) are parsed as follows: 00838 00839 First, the collectors gather any collections found in the arguments. Any 00840 reference type may be given as the value for a collector. For each collection 00841 given in the arguments, its validator (if any) is called. 00842 00843 Next, groups are expanded. If the group is implemented by a group generator, 00844 the generator is called. There are two special arguments which, if given to a 00845 group, have special meaning: 00846 00847 -prefix - a string to prepend to any export imported from this group 00848 -suffix - a string to append to any export imported from this group 00849 00850 Finally, individual export generators are called and all subs, generated or 00851 otherwise, are installed in the calling package. There is only one special 00852 argument for export generators: 00853 00854 -as - where to install the exported sub 00855 00856 Normally, C<-as> will contain an alternate name for the routine. It may, 00857 however, contain a reference to a scalar. If that is the case, a reference the 00858 generated routine will be placed in the scalar referenced by C<-as>. It will 00859 not be installed into the calling package. 00860 00861 =head2 Special Exporter Arguments 00862 00863 The generated exporter accept some special options, which may be passed as the 00864 first argument, in a hashref. 00865 00866 These options are: 00867 00868 into_level 00869 into 00870 generator 00871 installer 00872 00873 These override the same-named configuration options described in L</EXPORTER 00874 CONFIGURATION>. 00875 00876 =head1 SUBROUTINES 00877 00878 =head2 setup_exporter 00879 00880 This routine builds and installs an C<import> routine. It is called with one 00881 argument, a hashref containing the exporter configuration. Using this, it 00882 builds an exporter and installs it into the calling package with the name 00883 "import." In addition to the normal exporter configuration, a few named 00884 arguments may be passed in the hashref: 00885 00886 into - into what package should the exporter be installed 00887 into_level - into what level up the stack should the exporter be installed 00888 as - what name should the installed exporter be given 00889 00890 By default the exporter is installed with the name C<import> into the immediate 00891 caller of C<setup_exporter>. In other words, if your package calls 00892 C<setup_exporter> without providing any of the three above arguments, it will 00893 have an C<import> routine installed. 00894 00895 Providing both C<into> and C<into_level> will cause an exception to be thrown. 00896 00897 The exporter is built by C<L</build_exporter>>. 00898 00899 =head2 build_exporter 00900 00901 Given a standard exporter configuration, this routine builds and returns an 00902 exporter -- that is, a subroutine that can be installed as a class method to 00903 perform exporting on request. 00904 00905 Usually, this method is called by C<L</setup_exporter>>, which then installs 00906 the exporter as a package's import routine. 00907 00908 =head2 default_generator 00909 00910 This is BASIS::Sub::Exporter's default generator. It takes bits of configuration that 00911 have been gathered during the import and turns them into a coderef that can be 00912 installed. 00913 00914 my $code = default_generator(\%arg); 00915 00916 Passed arguments are: 00917 00918 class - the class on which the import method was called 00919 name - the name of the export being generated 00920 arg - the arguments to the generator 00921 col - the collections 00922 00923 generator - the generator to be used to build the export (code or scalar ref) 00924 00925 =head2 default_installer 00926 00927 This is BASIS::Sub::Exporter's default installer. It does what BASIS::Sub::Exporter 00928 promises: it installs code into the target package. 00929 00930 default_installer(\%arg, \@to_export); 00931 00932 Passed arguments are: 00933 00934 into - the package into which exports should be delivered 00935 00936 C<@to_export> is a list of name/value pairs. The default exporter assigns code 00937 (the values) to named slots (the names) in the given package. If the name is a 00938 scalar reference, the scalar reference is made to point to the code reference 00939 instead. 00940 00941 =head1 EXPORTS 00942 00943 BASIS::Sub::Exporter also offers its own exports: the C<setup_exporter> and 00944 C<build_exporter> routines described above. It also provides a special "setup" 00945 collector, which will set up an exporter using the parameters passed to it. 00946 00947 Note that the "setup" collector (seen in examples like the L</SYNOPSIS> above) 00948 uses C<build_exporter>, not C<setup_exporter>. This means that the special 00949 arguments like "into" and "as" for C<setup_exporter> are not accepted here. 00950 Instead, you may write something like: 00951 00952 use BASIS::Sub::Exporter 00953 { into => 'Target::Package' }, 00954 -setup => { 00955 -as => 'do_import', 00956 exports => [ ... ], 00957 } 00958 ; 00959 00960 Finding a good reason for wanting to do this is left as as exercise for the 00961 reader. 00962 00963 =head1 COMPARISONS 00964 00965 There are a whole mess of exporters on the CPAN. The features included in 00966 BASIS::Sub::Exporter set it apart from any existing Exporter. Here's a summary of 00967 some other exporters and how they compare. 00968 00969 =over 00970 00971 =item * L<Exporter> and co. 00972 00973 This is the standard Perl exporter. Its interface is a little clunky, but it's 00974 fast and ubiquitous. It can do some things that BASIS::Sub::Exporter can't: it can 00975 export things other than routines, it can import "everything in this group 00976 except this symbol," and some other more esoteric things. These features seem 00977 to go nearly entirely unused. 00978 00979 It always exports things exactly as they appear in the exporting module; it 00980 can't rename or customize routines. Its groups ("tags") can't be nested. 00981 00982 L<Exporter::Lite> is a whole lot like Exporter, but it does significantly less: 00983 it supports exporting symbols, but not groups, pattern matching, or negation. 00984 00985 The fact that BASIS::Sub::Exporter can't export symbols other than subroutines is 00986 a good idea, not a missing feature. 00987 00988 For simple uses, setting up BASIS::Sub::Exporter is about as easy as Exporter. For 00989 complex uses, BASIS::Sub::Exporter makes hard things possible, which would not be 00990 possible with Exporter. 00991 00992 When using a module that uses BASIS::Sub::Exporter, users familiar with Exporter will 00993 probably see no difference in the basics. These two lines do about the same 00994 thing in whether the exporting module uses Exporter or BASIS::Sub::Exporter. 00995 00996 use Some::Module qw(foo bar baz); 00997 use Some::Module qw(foo :bar baz); 00998 00999 The definition for exporting in Exporter.pm might look like this: 01000 01001 package Some::Module; 01002 use base qw(Exporter); 01003 our @EXPORT_OK = qw(foo bar baz quux); 01004 our %EXPORT_TAGS = (bar => [ qw(bar baz) ]); 01005 01006 Using BASIS::Sub::Exporter, it would look like this: 01007 01008 package Some::Module; 01009 use BASIS::Sub::Exporter -setup => { 01010 exports => [ qw(foo bar baz quux) ], 01011 groups => { bar => [ qw(bar baz) ]} 01012 }; 01013 01014 BASIS::Sub::Exporter respects inheritance, so that a package may export inherited 01015 routines, and will export the most inherited version. Exporting methods 01016 without currying away the invocant is a bad idea, but BASIS::Sub::Exporter allows you 01017 to do just that -- and anyway, there are other uses for this feature, like 01018 packages of exported subroutines which use inheritance specifically to allow 01019 more specialized, but similar, packages. 01020 01021 L<Exporter::Easy> provides a wrapper around the standard Exporter. It makes it 01022 simpler to build groups, but doesn't provide any more functionality. Because 01023 it is a front-end to Exporter, it will store your exporter's configuration in 01024 global package variables. 01025 01026 =item * Attribute-Based Exporters 01027 01028 Some exporters use attributes to mark variables to export. L<Exporter::Simple> 01029 supports exporting any kind of symbol, and supports groups. Using a module 01030 like Exporter or BASIS::Sub::Exporter, it's easy to look at one place and see what is 01031 exported, but it's impossible to look at a variable definition and see whether 01032 it is exported by that alone. Exporter::Simple makes this trade in reverse: 01033 each variable's declaration includes its export definition, but there is no one 01034 place to look to find a manifest of exports. 01035 01036 More importantly, Exporter::Simple does not add any new features to those of 01037 Exporter. In fact, like Exporter::Easy, it is just a front-end to Exporter, so 01038 it ends up storing its configuration in global package variables. (This means 01039 that there is one place to look for your exporter's manifest, actually. You 01040 can inspect the C<@EXPORT> package variables, and other related package 01041 variables, at runtime.) 01042 01043 L<Perl6::Export> isn't actually attribute based, but looks similar. Its syntax 01044 is borrowed from Perl 6, and implemented by a source filter. It is a prototype 01045 of an interface that is still being designed. It should probably be avoided 01046 for production work. On the other hand, L<Perl6::Export::Attrs> implements 01047 Perl 6-like exporting, but translates it into Perl 5 by providing attributes. 01048 01049 =item * Other Exporters 01050 01051 L<Exporter::Renaming> wraps the standard Exporter to allow it to export symbols 01052 with changed names. 01053 01054 L<Class::Exporter> performs a special kind of routine generation, giving each 01055 importing package an instance of your class, and then exporting the instance's 01056 methods as normal routines. (BASIS::Sub::Exporter, of course, can easily emulate this 01057 behavior, as shown above.) 01058 01059 L<Exporter::Tidy> implements a form of renaming (using its C<_map> argument) 01060 and of prefixing, and implements groups. It also avoids using package 01061 variables for its configuration. 01062 01063 =back 01064 01065 =head1 TODO 01066 01067 =over 01068 01069 =item * write a set of longer, more demonstrative examples 01070 01071 =item * solidify the "custom exporter" interface (see C<&default_exporter>) 01072 01073 =item * add an "always" group 01074 01075 =back 01076 01077 =head1 THANKS 01078 01079 Hans Dieter Pearcey provided helpful advice while I was writing BASIS::Sub::Exporter. 01080 Ian Langworth and Shawn Sorichetti asked some good questions and helped me 01081 improve my documentation quite a bit. Yuval Kogman helped me find a bunch of 01082 little problems. 01083 01084 Thanks, guys! 01085 01086 =head1 BUGS 01087 01088 Please report any bugs or feature requests through the web interface at 01089 L<http://rt.cpan.org>. I will be notified, and then you'll automatically be 01090 notified of progress on your bug as I make changes. 01091 01092 =head1 AUTHOR 01093 01094 Ricardo Signes <rjbs@cpan.org> 01095 01096 Modified by Andreas Schuh on 6/15/2012 in order to make it a subpackage 01097 of the SBIA namespace for inclusion with the BASIS package. 01098 01099 =head1 COPYRIGHT AND LICENSE 01100 01101 This software is copyright (c) 2007 by Ricardo Signes. 01102 01103 This is free software; you can redistribute it and/or modify it under 01104 the same terms as the Perl 5 programming language system itself. 01105 01106 =cut 01107