NAME
MooseX::ShortCut::BuildInstance - A shortcut to build Moose instances
SYNOPSIS
#!/user/bin/env perl
package Mineral;
use Moose;
use Types::Standard qw( Enum );
has 'type' =>(
isa => Enum[qw( Quartz Diamond Basalt Granite )],
is => 'ro'
);
package Identity;
use Moose::Role;
has 'name' =>( is => 'ro' );
use lib '../../../lib';
use MooseX::ShortCut::BuildInstance qw( should_re_use_classes build_instance );
should_re_use_classes( 1 );# To reuse build_instance
use Test::More;
use Test::Moose;
# First build of instance
my $paco = build_instance(
package => 'Pet::Rock',
superclasses =>['Mineral'],
roles =>['Identity'],
type => 'Quartz',
name => 'Paco',
);
does_ok( $paco, 'Identity', 'Check that the ' . $paco->meta->name . ' has an -Identity-' );
print'My ' . $paco->meta->name . ' made from -' . $paco->type . '- (a ' .
( join ', ', $paco->meta->superclasses ) . ') is called -' . $paco->name . "-\n";
# Next instance (If you don't want to call build_instance again)
my $Fransisco = Pet::Rock->new(
type => 'Diamond',
name => 'Fransisco',
);
does_ok( $Fransisco, 'Identity', 'Check that the ' . $Fransisco->meta->name . ' has an -Identity-' );
print'My ' . $Fransisco->meta->name . ' made from -' . $Fransisco->type . '- (a ' .
( join ', ', $Fransisco->meta->superclasses ) . ') is called -' . $Fransisco->name . "-\n";
# Another instance (reusing build_instance)
my $Gonzalo = build_instance(
package => 'Pet::Rock',
superclasses =>['Mineral'],
roles =>['Identity'],
type => 'Granite',
name => 'Gonzalo',
);
does_ok( $Gonzalo, 'Identity', 'Check that the ' . $Gonzalo->meta->name . ' has an -Identity-' );
print'My ' . $Gonzalo->meta->name . ' made from -' . $Gonzalo->type . '- (a ' .
( join ', ', $Gonzalo->meta->superclasses ) . ') is called -' . $Gonzalo->name . "-\n";
done_testing();
##############################################################################
# Output of SYNOPSIS
# 01:ok 1 - Check that the Pet::Rock has an -Identity-
# 02:My Pet::Rock made from -Quartz- (a Mineral) is called -Paco-
# 01:ok 1 - Check that the Pet::Rock has an -Identity-
# 02:My Pet::Rock made from -Diamond- (a Mineral) is called -Fransisco-
# 01:ok 1 - Check that the Pet::Rock has an -Identity-
# 02:My Pet::Rock made from -Granite- (a Mineral) is called -Gonzalo-
# 03:1..3
##############################################################################
DESCRIPTION
This module is a shortcut to custom build Moose class instances on the fly. The goal is to compose unique instances of Moose classes on the fly using a single function call with information describing required attributes, methods, inherited classes, and roles as well as any desired instance settings. This package will check for and fill in any missing pieces as needed so that your call can either be complex or very simple. The goal is to provide configurable instance building without stringing together a series of Class->method( %args ) calls.
The package can also be used as a class factory with the should_re_use_classes method.
Even though this is a Moose based class it provides a functional interface.
WARNING(S)
Moose (and I think perl 5) can't have two classes with the same name but different guts coexisting! This means that if you build a class (package) name on the fly while building an instance and then recompose a new class (package) with the same name but different functionality (different attributes, methods, inherited classes or roles) while composing a new instance on the fly then all calls to the old instance will use the new class functionality for execution. (Usually causing hard to troubleshoot failures). This is also true if you re-build a prebuilt class name inititally installed with 'use'.
MooseX::ShortCut::BuildInstance will warn if you overwrite named classes (packages) built on top of another class (package) also built by MooseX::ShortCut::BuildInstance. If you are using the 'build_instance' method to generate multiple instances of the same class (by 'package' name) with different attribute settings but built with the same functionality then you need to understand the purpose of the $re_use_classes global variable. An alternative to multiple calls straight to 'build_instance' is to call build_class separately and then just call ->new against the resulting class name over and over again. Another alternative is to leave the 'package' argument out of 'build_instance' and let this class create a unique by-instance anonymous class/package name.
MooseX::ShortCut::BuildInstance will also warn (but not stop you) if you try to overwrite a pre-loaded package initially installed with 'use' or 'require'.
The Types module in this package uses Type::Tiny which can, in the background, use Type::Tiny::XS. While in general this is a good thing you will need to make sure that Type::Tiny::XS is version 0.010 or newer since the older ones didn't support the 'Optional' method.
This package will clone the passed arguments to build_class and build_instance since the references are destructivly parsed. If that is not what you want then use the method set_args_cloning to manage the desired process. Where this is likley to go south is if your passed arguments contain a deep perl data set or reference that you want shared. In this case clone only the bits you want cloned on the script side.
Functions for Export
build_instance( %args|\%args )
Definition: This method is used to create a Moose instance on the fly. It assumes that you do not have the class pre-built and will look for the needed information to compose a new class as well. Basically this passes the %args intact to build_class first. All the relevant class building pieces will be used and removed from the args and then this method will run $returned_class_name->new( %remaining_args ) with what is left.
Accepts: a hash or hashref of arguments. They must include the necessary information to build a class. (if you already have a class just call $class->new( %args ); instead of this method!) This hashref can also contain any attribute settings for the instance as well. See build_class for more information.
Returns: This will return a blessed instance of your new class with the passed attribute settings implemented.
build_class( %args|\%args )
Definition: This function is used to compose a Moose class on the fly. The the goal is to allow for as much or as little class definition as you want to be provided by one function call. The goal is also to remove as much of the boilerplate and logic sequences for class building as possible and let this package handle that. The function begins by using the Moose::Meta::Class->class(%args) method. For this part the function specifically uses the argument callouts 'package', 'superclasses', and 'roles'. Any necessary missing pieces will be provided. Even though Moose::Meta::Class->class(%args) allows for the package name to be called as the first element of an odd numbered list this implementation does not. To define a 'package' name it must be set as the value of the 'package' key in the %args. This function then takes the following arguements; 'add_attributes', 'add_methods', and 'add_roles_in_sequence' and implements them in that order. The implementation of these values is done with Moose::Util 'apply_all_roles' and the meta capability in Moose.
Accepts: a hash or hashref of arguments. Six keys are stripped from the hash or hash ref of arguments. These keys are always used to build the class. They are never passed on to %remaining_args.
The first three key->value pairs are consumed simultaneously. They are;
package: This is the name (a string) that the new instance of a this class is blessed under. If this key is not provided the package will generate a generic name. This will overwrite any class built earlier with the same name.
accepts: a string
superclasses: this is intentionally the same key from Moose::Meta::Class->create.
accepts: a recognizable (by Moose) class name
roles: this is intentionally the same key from Moose::Meta::Class ->create.
accepts: a recognizable (by Moose) class name
The second three key->value pairs are consumed in the following sequence. They are;
add_attributes: this will add attributes to the class using the Moose::Meta::Class->add_attribute method. Because these definitions are passed as key / value pairs in a hash ref they are not added in any specific order.
accepts: a hash ref where the keys are attribute names and the values are hash refs of the normal definitions used to define a Moose attribute.
add_methods: this will add methods to the class using the Moose::Meta::Class->add_method method. Because these definitions are passed as key / value pairs in a hash ref they are not added in any specific order.
accepts: a hash ref where the keys are method names and the values are anonymous subroutines or subroutine references.
add_roles_in_sequence: this will compose, in sequence, each role in the array ref into the class built on the prior three arguments using Moose::Util apply_all_roles. This will allow an added role to 'require' elements of a role earlier in the sequence. The roles implemented with the role key are installed first and in a group. Then these roles are installed one at a time.
accepts: an array ref list of roles recognizable (by Moose) as roles
Returns: This will check the caller and see if it wants an array or a scalar. In array context it returns the new class name and a hash ref of the unused hash key/value pairs. These are presumably the arguments for the instance. If the requested return is a scalar it just returns the name of the newly created class.
should_re_use_classes( $bool )
This sets/changes the global variable MooseX::ShortCut::BuildInstance::re_use_classes
set_class_immutability( $bool )
This sets/changes the global variable MooseX::ShortCut::BuildInstance::make_classes_immutable
set_args_cloning( $bool )
This sets/changes the global variable MooseX::ShortCut::BuildInstance::should_clone_args
GLOBAL VARIABLES
$MooseX::ShortCut::BuildInstance::anonymous_class_count
This is an integer that increments and appends to the anonymous package name for each new anonymous package (class) created.
$MooseX::ShortCut::BuildInstance::built_classes
This is a hashref that tracks the class names ('package's) built buy this class to manage duplicate build behaviour.
$MooseX::ShortCut::BuildInstance::re_use_classes
This is a boolean (1|0) variable that tracks if the class should overwrite or re-use a package name (and the defined class) from a prior 'build_class' call. If the package name is overwritten it will cluck in warning since any changes will affect active instances of prior class builds with the same name. If you wish to avoid changing old built behaviour at the risk of not installing new behaviour then set this variable to true. No warning will be provided if new requested class behaviour is discarded. The class reuse behaviour can be changed with the exported method should_re_use_classes . This does not apply to pre-loaded classes. For pre-loaded classes this package will cluck and then overwrite every time.
Default: False = warn then overwrite
$MooseX::ShortCut::BuildInstance::make_classes_immutable
This is a boolean (1|0) variable that manages whether a class is immutabilized at the end of creation. This can be changed with the exported method set_class_immutability .
Default: True = always immutabilize classes after building
$MooseX::ShortCut::BuildInstance::should_clone_args
This is a boolean (1|0) variable that manages whether a the arguments passed to build_instance and build_class are cloned (using Clone ) the arguments to both of these are processed destructivly so generally you would want them cloned but not in every case. If you want cloning to be managed on the script side set this global variable to 0. Where this is likley to be helpful is if your passed arguments contain a deep perl data set or reference that you want shared. In this case clone only the bits you want cloned on the script side.
Default: True = always clone arguments
Build/Install from Source
1. Download a compressed file with the code
2. Extract the code from the compressed file.
If you are using tar this should work:
tar -zxvf Spreadsheet-XLSX-Reader-LibXML-v0.xx.tar.gz
3. Change (cd) into the extracted directory
4. Run the following
(For Windows find what version of make was used to compile your perl)
perl -V:make
(for Windows below substitute the correct make function (s/make/dmake/g)?)
>perl Makefile.PL
>make
>make test
>make install # As sudo/root
>make clean
SUPPORT
TODO
2. Add an explicit 'export' setup call using Moose::Exporter as an action key in 'build_class'
AUTHOR
Jed Lund
jandrew@cpan.org
COPYRIGHT
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.
This software is copyrighted (c) 2012, 2016 by Jed Lund
Dependencies
5.010 (for use of defined or //)
Carp - cluck
Moose::Util - apply_all_roles
Type::Tiny - 1.000
SEE ALSO
Moose::Meta::Class ->create
Moose::Util ->with_traits
All debug lines in this module are warn statements and are hidden behind '###InternalBuilDInstancE'. When exposed they can be redirected to log files with Log::Shiras::TapWarn.