X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FPackage%2FVariant.pm;h=b9ed5a6040ddc1289ff2206a6c9f8819fa51ab3e;hb=75bb0c03ccf8b583f3214fffc7cdfbebbdeabddd;hp=55dd25cec96fd18a8da68c849eb4d4005dfb6fa9;hpb=eacc208a1204b9a9187686de93e8613410c94269;p=p5sagit%2FPackage-Variant.git diff --git a/lib/Package/Variant.pm b/lib/Package/Variant.pm index 55dd25c..b9ed5a6 100644 --- a/lib/Package/Variant.pm +++ b/lib/Package/Variant.pm @@ -1,9 +1,11 @@ package Package::Variant; use strictures 1; -use Carp qw( croak ); +use Import::Into; +use Module::Runtime qw(use_module); +use Carp qw(croak); -our $VERSION = '1.000000'; # 1.0.0 +our $VERSION = '1.001001'; # 1.1.1 $VERSION = eval $VERSION; @@ -47,6 +49,10 @@ my $sanitize_importing = sub { return \@imports; }; +my $sub_namer = eval { + require Sub::Name; sub { shift if @_ > 2; Sub::Name::subname(@_) } +} || sub { $_[-1] }; + sub import { my $target = caller; my $me = shift; @@ -58,6 +64,7 @@ sub import { $Variable{$variable} = { anon => $anon, args => { + make_variant => 'make_variant', %args, importing => $me->$sanitize_importing($args{importing}), }, @@ -73,7 +80,7 @@ sub import { *{"${target}::${as}"} = sub { $me->build_variant_of($variable, @_); }; - }; + } unless $args{no_import}; my $subs = $Variable{$variable}{subs}; foreach my $name (keys %$subs) { *{"${target}::${name}"} = sub { @@ -88,31 +95,21 @@ sub import { sub build_variant_of { my ($me, $variable, @args) = @_; my $variant_name = "${variable}::_Variant_".++$Variable{$variable}{anon}; - my $import = $Variable{$variable}{args}{importing}; - my $setup = join("\n", - "package ${variant_name};", - (map sprintf( - q!use %s %s;!, - $import->[$_][0], - scalar(@{$import->[$_][1]}) - ? sprintf( - q!@{$import->[%d][1]}!, - $_, - ) - : '', - ), 0..$#$import), - "1;", - ); - eval $setup - or die "evaling ${setup} failed: $@"; + foreach my $to_import (@{$Variable{$variable}{args}{importing}}) { + my ($pkg, $args) = @$to_import; + use_module($pkg)->import::into($variant_name, @{$args}); + } my $subs = $Variable{$variable}{subs}; local @{$subs}{keys %$subs} = map $variant_name->can($_), keys %$subs; local $Variable{$variable}{install} = sub { - my ($name, $ref) = @_; + my $full_name = "${variant_name}::".shift; + + my $ref = $sub_namer->($full_name, @_); + no strict 'refs'; - *{"${variant_name}::${name}"} = $ref; + *$full_name = $ref; }; - $variable->make_variant($variant_name, @args); + $variable->${\$Variable{$variable}{args}{make_variant}}($variant_name, @args); return $variant_name; } @@ -133,7 +130,7 @@ Package::Variant - Parameterizable packages # what modules to 'use' importing => ['Moo::Role'], # proxied subroutines - subs => [qw( has around before after extends )], + subs => [ qw(has around before after with) ], sub make_variant { my ($class, $target_package, %arguments) = @_; @@ -230,7 +227,7 @@ your users can get a variant generating subroutine by simply importing your package. use My::Variant; - my $new_variant_package = Variant( @variant_arguments ); + my $new_variant_package = Variant(@variant_arguments); The package is now fully initialized and used. You can import the subroutine under a different name by specifying an C argument. @@ -258,9 +255,9 @@ are created. =head2 importing This option is a hash reference mapping package names to array references -containing import arguments. The packages will be Cd with the given +containing import arguments. The packages will be imported with the given arguments by every variation before the L method is asked -to create the package. +to create the package (this is done using L). If import order is important to you, you can also pass the C arguments as a flat array reference: @@ -282,7 +279,7 @@ empty or not specified, If you just want to import a single package's default exports, you can also pass a string instead: - use PAckage::Variant importing => 'Package'; + use Package::Variant importing => 'Package'; =head2 subs @@ -325,7 +322,7 @@ The following options can be specified when importing: =item * B use Some::Variant::Package as => 'Foo'; - my $variant_package = Foo( @arguments ); + my $variant_package = Foo(@arguments); Exports the generator subroutine under a different name than the default. @@ -338,7 +335,7 @@ These methods are available on C itself. =head2 build_variation_of my $variant_package = Package::Variant - ->build_variation_of( $variable_package, @arguments ); + ->build_variation_of($variable_package, @arguments); This is the dynamic method of creating new variants. It takes the C<$variable_package>, which is a pre-declared variable package, and a set @@ -360,11 +357,14 @@ following exports will be available in your variable package: =head2 install - install( $method_name, $code_reference ); + install($method_name, $code_reference); Installs a method with the given C<$method_name> into the newly created variant package. The C<$code_reference> will be used as the body for the -method. +method, and if L is available the coderef will be named. If you +want to name it something else, then use: + + install($method_name, $name_to_use, $code_reference); =head1 AUTHOR @@ -376,7 +376,7 @@ phaylon - Robert Sedlacek (cpan:PHAYLON) =head1 COPYRIGHT -Copyright (c) 2010-2011 the C L and +Copyright (c) 2010-2012 the C L and L as listed above. =head1 LICENSE