The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

MooseX::ShortCut::BuildInstance - A shortcut to build Moose instances

Build Status perl version Coverage Status kwalitee

SYNOPSIS

        #!perl
        package Mineral;
        use Moose;

        has 'type' =>( is => 'ro' );

        package Identity;
        use Moose::Role;

        has 'name' =>( is => 'ro' );

        use MooseX::ShortCut::BuildInstance;
        use Test::More;
        use Test::Moose;

        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";
        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-
    # 03:1..1
    ##############################################################################

    

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 instance settings to apply in a DCI fashion. 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

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)

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.

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.

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 )

set_class_immutability( $bool )

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 .

    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 .

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

    1. Pending ideas

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, 2015 by Jed Lund

Dependencies

SEE ALSO