diff options
author | Chad Granum <exodist7@gmail.com> | 2016-08-20 21:41:07 -0700 |
---|---|---|
committer | Chad Granum <exodist7@gmail.com> | 2016-08-20 21:41:07 -0700 |
commit | 84bdf0f942b48aea3548d2279ee4c3ba99ceab45 (patch) | |
tree | 5d3fba34d60618ea7c1f4f8f6bf9b5064c40a160 | |
parent | 0a26d3f1485233e059b095ddbf053a6b7aa953a8 (diff) |
Enhance version-tags
-rw-r--r-- | Changes | 5 | ||||
-rw-r--r-- | lib/Importer.pm | 90 | ||||
-rw-r--r-- | t/versions.t | 34 |
3 files changed, 124 insertions, 5 deletions
@@ -1,5 +1,10 @@ {{$NEXT}} + - Add polish to version-sets + - Add '*' version for common things + - Do not allow tags or versions inside a version specification + - More documentation for version-sets + 0.015 2016-08-20 15:26:23-07:00 America/Los_Angeles (TRIAL RELEASE) - Add support for version-sets diff --git a/lib/Importer.pm b/lib/Importer.pm index 17cffa4..a8680f5 100644 --- a/lib/Importer.pm +++ b/lib/Importer.pm @@ -419,22 +419,62 @@ sub _build_menu { } @$export_fail } : undef; + my $common_v = delete $export_vers->{'*'}; + my $versions = { v0 => { # Add base as v0, do not use the same hashref to avoid self-refrencing lookup => $lookup, exports => $exports, - tags => $tags, fail => $fail, generate => $generate, magic => $export_magic, }, }; for my $v (keys %$export_vers) { + $self->croak("Cannot use 'export_versions' inside a version!") + if $export_vers->{$v}->{export_versions}; + + $self->croak("Cannot use 'export_tags' inside a version!") + if $export_vers->{$v}->{export_tags}; + my $submenu = $self->_build_menu($into, $export_vers->{$v}, $new_style); - $tags->{$v} ||= [ "+$v", @{$submenu->{tags}->{DEFAULT}} ]; + delete $submenu->{versions}; + my $t = delete $submenu->{tags}; + + $tags->{$v} ||= [ "+$v", @{$t->{DEFAULT}} ]; $versions->{$v} ||= $submenu; } + # This itentionally effects v0 which has the same refs as the root menu + if ($common_v) { + my $common = $self->_build_menu($into, $common_v, $new_style); + + for my $v (keys %$versions) { + my $vd = $versions->{$v}; + + # Hashes, easy to mix + for my $simple (qw/lookup exports magic fail/) { + my $mix = $common->{$simple} || next; + my $it = $vd->{$simple} || {}; + %$it = (%$mix, %$it); + } + + # generate is a sub that returns undef on no match, first use the version one, fallback to common one + if (my $cgen = $common->{generate}) { + if (my $vgen = $vd->{generate}) { + $vd->{generate} = sub { $vgen->(@_) or $cgen->(@_) }; + } + else { + $vd->{generate} = $cgen; + } + } + + # Update the tag added for the version + my %seen = (); + @{$tags->{$v}} = grep { !$seen{$_} } @{$tags->{$v}}, @{$common->{tags}->{DEFAULT}}; + } + } + $self->{menu_for} = $into; return $self->{menu} = { lookup => $lookup, @@ -1138,6 +1178,11 @@ changes. ); our %EXPORT_VERSIONS = ( + # The '*' version is special, it gets mixed into all versions + # (including v0 and the root menu). + '*' => { + export => [qw/apple pie/], + }, v1 => { export_anon => { foo => \&foo_v1, # Export the v1 variant of foo() @@ -1162,8 +1207,45 @@ This will import the v1 latest foo() use Importer 'My::Thing' => qw/-latest foo/; -B<NOTE>: Nothing is inherited from the package variables/root menu. Anything -you want in a specific version must be listed there. +=head3 ALLOWED KEYS FOR VERSION-SET SPECIFICATIONS + +=over 4 + +=item export => \@default_list + +Same as C<@EXPORT>, but specific to the version. + +=item export_ok => \@allowed_list + +Same as C<@EXPORT_OK>, but specific to the version. + +=item export_fail => \@fail_list + +Same as C<@EXPORT_FAIL>, but specific to the version. + +=item export_anon => { name => sub { ... }, ... } + +Same as C<%EXPORT_ANON>, but specific to the version. + +=item export_magic => { name => sub { ... }, ... } + +Same as C<%EXPORT_MAGIC>, but specific to the version. + +=item export_gen => { name => sub { return sub { ... } }, ... } + +Same as C<%EXPORT_GEN>, but specific to the version. + +=back + +=head3 NOTES + +=over 4 + +=item Nothing is inherited from the package variables/root menu. + +=item The C<'*'> version is mixed into all versions, including root/v0 + +=back =head1 CLASS METHODS diff --git a/t/versions.t b/t/versions.t index f988370..ff4d201 100644 --- a/t/versions.t +++ b/t/versions.t @@ -7,6 +7,10 @@ BEGIN { $INC{'My/Exporter.pm'} = 1; package My::Exporter; + sub x { 'x' } + sub y { 'y' } + sub z { 'z' } + sub IMPORTER_MENU { return ( export_anon => { @@ -17,6 +21,20 @@ BEGIN { e => sub { 'e0' }, }, export_versions => { + '*' => { + export => [qw/x/], + export_ok => [qw/y z/], + generate => sub { + my $symbol = shift; + my ($sig, $name) = ($symbol =~ m/^(\W?)(.*)$/); + $sig ||= '&'; + + return undef unless $sig eq '&'; + return undef unless $name eq 'g1'; + + return sub { 'g1' }; + }, + }, v1 => { export => [qw/a b c/], export_anon => { @@ -24,6 +42,16 @@ BEGIN { b => sub { 'b1' }, c => sub { 'c1' }, }, + generate => sub { + my $symbol = shift; + my ($sig, $name) = ($symbol =~ m/^(\W?)(.*)$/); + $sig ||= '&'; + + return undef unless $sig eq '&'; + return undef unless $name eq 'g2'; + + return sub { 'g2' }; + }, }, v2 => { export => [qw/a b c/], @@ -64,11 +92,15 @@ BEGIN { { package My::Importer::C; - use Importer 'My::Exporter' => ':v1'; + use Importer 'My::Exporter' => qw/:v1 g1 g2/; ::is(a(), 'a1', "got v1 a()"); ::is(b(), 'b1', "got v1 b()"); ::is(c(), 'c1', "got v1 c()"); + ::is(x(), 'x', "got common x()"); + + ::is(g1(), 'g1', "Used common generate"); + ::is(g2(), 'g2', "Used version generate"); ::ok(!__PACKAGE__->can('d'), "Did not import d()"); } |