X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FPackage%2FVariant.pm;h=091850fa6dc0247580943a204e4d776dfcc5b281;hb=ca6d96a268693e998034e23a4506964df4f0465b;hp=a242d93cb8f651a96e2db2d68ebb5fbd26aa4e4e;hpb=85dcc3b1136674972eca457437db2ee696eb6767;p=p5sagit%2FPackage-Variant.git diff --git a/lib/Package/Variant.pm b/lib/Package/Variant.pm index a242d93..091850f 100644 --- a/lib/Package/Variant.pm +++ b/lib/Package/Variant.pm @@ -94,9 +94,17 @@ sub import { }; } +sub build_variant_package_name { + my ($me, $variable, @args) = @_; + if ($variable->can('make_variant_package_name')) { + return $variable->make_variant_package_name(@args); + } + return "${variable}::_Variant_".++$Variable{$variable}{anon}; +} + sub build_variant_of { my ($me, $variable, @args) = @_; - my $variant_name = "${variable}::_Variant_".++$Variable{$variable}{anon}; + my $variant_name = $me->build_variant_package_name($variable, @args); foreach my $to_import (@{$Variable{$variable}{args}{importing}}) { my ($pkg, $args) = @$to_import; require_module $pkg; @@ -127,6 +135,8 @@ Package::Variant - Parameterizable packages =head1 SYNOPSIS +Creation of anonymous variants: + # declaring a variable Moo role package My::VariableRole::ObjectAttr; use strictures 1; @@ -160,6 +170,50 @@ Package::Variant - Parameterizable packages my $obj = My::Class::WithObjectAttr->new; $obj->some_obj; # returns a Some::Class instance +And the same thing, only with named variants: + + # declaring a variable Moo role that can be named + package My::VariableRole::ObjectAttrNamed; + use strictures 1; + use Package::Variant importing => ['Moo::Role'], + subs => [ qw(has around before after with) ]; + use Module::Runtime 'module_notional_filename'; # only if you need protection + + # this method is run at variant creation time to determine its custom + # package name. it can use the arguments or do something entirely else. + sub make_variant_package_name { + my ($class, $package, %arguments) = @_; + $package = "Private::$package"; # you can munge the input here if you like + # only if you *need* protection + die "Won't clobber $package" if $INC{module_notional_filename $package}; + return $package; + } + + # same as in the example above, except for the argument list. in this example + # $package is the user input, and + # $target_package is the actual package in which the variant gets installed + sub make_variant { + my ($class, $target_package, $package, %arguments) = @_; + my $name = $arguments{name}; + has $name => (is => 'lazy'); + install "_build_${name}" => sub {return $arguments{class}->new}; + } + + # using the role + package My::Class::WithObjectAttr; + use strictures 1; + use Moo; + use My::VariableRole::ObjectAttrNamed; + + # create the role under a specific name + ObjectAttrNamed "My::Role" => (name => 'some_obj', class => 'Some::Class'); + # and use it + with "Private::My::Role"; + + # using our class + my $obj = My::Class::WithObjectAttr->new; + $obj->some_obj; # returns a Some::Class instance + =head1 DESCRIPTION This module allows you to build a variable package that contains a package @@ -316,6 +370,19 @@ declared in L to customize the new variant package. This is a class method receiving the C<$target> package and the C<@arguments> defining the requested variant. +=head2 make_variant_package_name + + Some::Variant::Package->make_variant_package_name( @arguments ); + +B If present, this method will be +used to determine the package name for a particular variant being constructed. + +If you do not implement it, a unique package name something like + + Some::Variant::Package::_Variant_A003 + +will be created for you. + =head2 import use Some::Variant::Package;