MooseX::AttributeInflate - Auto-inflate your Moose attribute objects


MooseX-AttributeInflate documentation Contained in the MooseX-AttributeInflate distribution.

Index


Code Index:

NAME

Top

MooseX::AttributeInflate - Auto-inflate your Moose attribute objects

VERSION

Top

Version 0.03

SYNOPSIS

Top

Lazily constructs ("inflates") an object attribute, optionally using constant parameters.

    package MyClass;
    use MooseX::AttributeInflate;

    has_inflated 'helper' => (
        is => 'ro', isa => 'MyHelper'
    );

    # OR, explicitly

    has 'helper' => (
        is => 'ro', isa => 'MyHelper',
        traits => [qw/Inflated/],
        inflate_args => [],
        inflate_method => 'new',
    );

    my $obj = MyClass->new();
    $obj->helper->help();

DESCRIPTION

Top

For each attribute defined with has_inflated, this module overrides the default for that attribute, calling instead that attribute's type's constructor. The construction is done lazily unless overriden with lazy => 0.

See has_inflated for options and more detail.

Construction only works with objects; an exception will be thrown if the isa type of this attribute is not a decendant of Object (this includes ArrayRef and HashRef types).

Alternatively, you may use the attribute trait Inflated to compose an attribute with other attribute trais.

EXPORTS

Top

has_inflated

Just like Moose's has, but applies the attribute trait Inflated and defaults lazy to be on. See EXPORTED FUNCTIONS in Moose for more detail on has.

If lazy_build is defined, the canonical build method (e.g. _build_helper) IS NOT called. Otherwise, lazy_build works as usual, setting required and installing a clearer and predicate.

Additional options:

lazy

Defaults on, but can be turned off with lazy => 0.

lazy_build

Just like Moose's lazy_build, but does not call the canonical builder method (e.g. _build_$name).

inflate_method

The name of the constructor to use. Defaults to 'new'.

inflate_args

The arguments to pass to the constructor. Defaults to an empty list.

SEE ALSO

Top

MooseX::CurriedHandles - combine with this module for auto-inflating moose curry!

http://github.com/stash/moosex-attributeinflate/ - Github repository

AUTHOR

Top

Stash <jstash+cpan@gmail.com>

BUGS

Top

Please report any bugs or feature requests to bug-moosex-attrinflate at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=MooseX-AttributeInflate. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc MooseX::AttributeInflate




You can also look for information at:

* #moose on irc.perl.org

irc://irc.perl.org#moose

* RT: CPAN's request tracker

http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooseX-AttributeInflate

* AnnoCPAN: Annotated CPAN documentation

http://annocpan.org/dist/MooseX-AttributeInflate

* CPAN Ratings

http://cpanratings.perl.org/d/MooseX-AttributeInflate

* Search CPAN

http://search.cpan.org/dist/MooseX-AttributeInflate

ACKNOWLEDGEMENTS

Top

konobi for Meta-advice and CPAN help

perigrin, doy, Sartak and other #moose folks for suggestions & patches.

COPYRIGHT & LICENSE

Top


MooseX-AttributeInflate documentation Contained in the MooseX-AttributeInflate distribution.

package MooseX::AttributeInflate;
use warnings;
use strict;
use Moose ();
use Moose::Exporter ();

our $VERSION = '0.03';

Moose::Exporter->setup_import_methods(
    with_caller => ['has_inflated'],
    also => 'Moose',
);

sub has_inflated {
    my $caller = shift;
    my $name = shift;
    my %options = @_;
    $options{traits} ||= [];
    unshift @{$options{traits}}, 'Inflated';
    Class::MOP::Class->initialize($caller)->add_attribute($name, %options);
}

package MooseX::Meta::Attribute::Trait::Inflated;
use Moose::Role;
use Moose::Util::TypeConstraints ();

has 'inflate_args' => (
    is => 'rw', isa => 'ArrayRef',
    predicate => 'has_inflate_args'
);
has 'inflate_method' => (
    is => 'rw', isa => 'Str',
    default => 'new'
);

sub inflate {
    my $self = shift;
    my $class = $self->type_constraint->name;
    my $ctor = $self->inflate_method;
    return $class->$ctor($self->has_inflate_args ? @{$self->inflate_args} : ());
}

around 'new' => sub {
    my $code = shift;

    my $class = shift;
    my $name = shift;
    my %options = @_;

    $options{lazy} = 1 unless exists $options{lazy};

    if ($options{lazy_build}) {
        delete $options{lazy_build};
        delete $options{builder};
        $options{lazy} = 1;
        $options{required} = 1;
        if ($name =~ /^_/) {
            $options{predicate} ||= "_has$name";
            $options{clearer} ||= "_clear$name";
        }
        else {
            $options{predicate} ||= "has_$name";
            $options{clearer} ||= "clear_$name";
        }
    }
    $options{required} = 1;
    $options{default} = sub {
        $_[0]->meta->get_attribute($name)->inflate()
    };

    my $self = $class->$code($name,%options);

    my $type = $self->type_constraint;
    confess "type constraint isn't a subtype of Object"
        unless $type->is_subtype_of('Object');

    return $self;
};

if ($Moose::VERSION < 1.09) {
    around 'legal_options_for_inheritance' => sub {
        my $code = shift;
        my $self = shift;
        return ($self->$code(@_), 'inflate_args', 'inflate_method')
    };
}


no Moose::Role;

package # happy PAUSE
    Moose::Meta::Attribute::Custom::Trait::Inflated;
sub register_implementation { 'MooseX::Meta::Attribute::Trait::Inflated' }

1;