Skip to content

hartzell/moox-strictconstructor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

81 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NAME

MooX::StrictConstructor - Make your Moo-based object constructors blow up on unknown attributes.

VERSION

version 0.011

SYNOPSIS

package My::Class;

use Moo;
use MooX::StrictConstructor;

has 'size' => ( is => 'rw');

# then somewhere else, when constructing a new instance
# of My::Class ...

# this blows up because color is not a known attribute
My::Class->new( size => 5, color => 'blue' );

DESCRIPTION

Simply loading this module makes your constructors "strict". If your constructor is called with an attribute init argument that your class does not declare, then it dies. This is a great way to catch small typos.

Your application can use Carp::Always to generate stack traces on die. Previously all exceptions contained traces, but this could potentially leak sensitive information, e.g.

My::Sensitive::Class->new( password => $sensitive, extra_value => 'foo' );

STANDING ON THE SHOULDERS OF ...

Most of this package was lifted from MooX::InsideOut and most of the Role that implements the strictness was lifted from MooseX::StrictConstructor.

SUBVERTING STRICTNESS

MooseX::StrictConstructor documents two tricks for subverting strictness and avoid having problematic arguments cause an exception: handling them in BUILD or handle them in BUILDARGS.

In MooX::StrictConstructor you can use a BUILDARGS function to handle them, e.g. this will allow you to pass in a parameter called "spy" without raising an exception. Useful? Only you can tell.

sub BUILDARGS {
    my ($self, %params) = @_;
    my $spy delete $params{spy};
    # do something useful with the spy param
    return \%params;
}

Because BUILD methods are run after an object has been constructed and this code runs before the object is constructed the BUILD trick will not work.

BUGS/ODDITIES

Inheritance

A class that uses MooX::StrictConstructor but extends another class that does not will not be handled properly. This code hooks into the constructor as it is being strung up (literally) and that happens in the parent class, not the one using strict.

A class that inherits from a Moose based class will discover that the Moose class's attributes are disallowed. Given sufficient Moose meta knowledge it might be possible to work around this. I'd appreciate pull requests and or an outline of a solution.

Subverting strictness

MooseX::StrictConstructor documents a trick for subverting strictness using BUILD. This does not work here because strictness is enforced in the early stage of object construction but the BUILD subs are run after the objects has been built.

Interactions with namespace::clean

MooX::StrictConstructor creates a new method that namespace::clean will over-zealously clean. Workarounds include using MooX::StrictConstructor after namespace::autoclean or telling namespace::clean to ignore new with something like:

use namespace::clean -except => ['new','meta'];

CONTRIBUTING

Given an appropriate Perl and App-cpanminus, you can set up a development environment like so:

export PATH=$(pwd)/local/bin:$PATH
export PERL5LIB=$(pwd)/local/lib/perl5/
cpanm -L local Dist::Zilla
dzil authordeps --missing | cpanm -L local
dzil listdeps --develop | cpanm -L local

Your changes should pass both the tests (t/*) and the extended tests (xt/*). Dzil can run them all for you:

dzil xtest

SEE ALSO

AUTHOR

George Hartzell <[email protected]>

COPYRIGHT AND LICENSE

This software is copyright (c) 2020 by George Hartzell.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

About

Strict constructors for Moo classes.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages