.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "MooX::StrictConstructor 3pm" .TH MooX::StrictConstructor 3pm "2022-12-06" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" MooX::StrictConstructor \- Make your Moo\-based object constructors blow up on unknown attributes. .SH "VERSION" .IX Header "VERSION" version 0.011 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& package My::Class; \& \& use Moo; \& use MooX::StrictConstructor; \& \& has \*(Aqsize\*(Aq => ( is => \*(Aqrw\*(Aq); \& \& # 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 => \*(Aqblue\*(Aq ); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Simply loading this module makes your constructors \*(L"strict\*(R". 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. .PP Your application can use Carp::Always to generate stack traces on \f(CW\*(C`die\*(C'\fR. Previously all exceptions contained traces, but this could potentially leak sensitive information, e.g. .PP .Vb 1 \& My::Sensitive::Class\->new( password => $sensitive, extra_value => \*(Aqfoo\*(Aq ); .Ve .SS "\s-1STANDING ON THE SHOULDERS OF ...\s0" .IX Subsection "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. .SS "\s-1SUBVERTING STRICTNESS\s0" .IX Subsection "SUBVERTING STRICTNESS" MooseX::StrictConstructor documents two tricks for subverting strictness and avoid having problematic arguments cause an exception: handling them in \s-1BUILD\s0 or handle them in \s-1BUILDARGS.\s0 .PP In MooX::StrictConstructor you can use a \s-1BUILDARGS\s0 function to handle them, e.g. this will allow you to pass in a parameter called \*(L"spy\*(R" without raising an exception. Useful? Only you can tell. .PP .Vb 6 \& sub BUILDARGS { \& my ($self, %params) = @_; \& my $spy delete $params{spy}; \& # do something useful with the spy param \& return \e%params; \& } .Ve .PP Because \f(CW\*(C`BUILD\*(C'\fR methods are run after an object has been constructed and this code runs before the object is constructed the \f(CW\*(C`BUILD\*(C'\fR trick will not work. .SH "BUGS/ODDITIES" .IX Header "BUGS/ODDITIES" .SS "Inheritance" .IX Subsection "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. .PP 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. .SS "Subverting strictness" .IX Subsection "Subverting strictness" MooseX::StrictConstructor documents a trick for subverting strictness using \s-1BUILD.\s0 This does not work here because strictness is enforced in the early stage of object construction but the \&\s-1BUILD\s0 subs are run after the objects has been built. .SS "Interactions with namespace::clean" .IX Subsection "Interactions with namespace::clean" MooX::StrictConstructor creates a \f(CW\*(C`new\*(C'\fR method that namespace::clean will over-zealously clean. Workarounds include using MooX::StrictConstructor \fBafter\fR namespace::autoclean or telling namespace::clean to ignore \f(CW\*(C`new\*(C'\fR with something like: .PP .Vb 1 \& use namespace::clean \-except => [\*(Aqnew\*(Aq,\*(Aqmeta\*(Aq]; .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 MooX::InsideOut .IP "\(bu" 4 MooseX::StrictConstructor .SH "AUTHOR" .IX Header "AUTHOR" George Hartzell .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2020 by George Hartzell. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.