summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Granum <exodist7@gmail.com>2016-08-20 21:41:07 -0700
committerChad Granum <exodist7@gmail.com>2016-08-20 21:41:07 -0700
commit84bdf0f942b48aea3548d2279ee4c3ba99ceab45 (patch)
tree5d3fba34d60618ea7c1f4f8f6bf9b5064c40a160
parent0a26d3f1485233e059b095ddbf053a6b7aa953a8 (diff)
Enhance version-tags
-rw-r--r--Changes5
-rw-r--r--lib/Importer.pm90
-rw-r--r--t/versions.t34
3 files changed, 124 insertions, 5 deletions
diff --git a/Changes b/Changes
index 700257d..9f76e47 100644
--- a/Changes
+++ b/Changes
@@ -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()");
}