Class::Tiny uses custom accessors if they are defined before the
use Class::Tiny
statement in a package. This module creates custom
accessors that behave as standard Class::Tiny
accessors except that
they apply type constraints (isa
relationships). Type constraints
can come from Type::Tiny, MooseX::Types, MooX::Types::MooseLike,
MouseX::Types, or Specio. Alternatively, constraints can be applied
using the technique described in
"Constraints without a type system".
Example of a class using this package:
package SampleClass;
use Scalar::Util qw(looks_like_number);
use Type::Tiny;
# Create the type constraint
use vars::i '$MediumInteger' = Type::Tiny->new(
name => 'MediumInteger',
constraint => sub { looks_like_number($_) and $_ >= 10 and $_ < 20 }
);
use Class::Tiny::ConstrainedAccessor {
medint => $MediumInteger, # create accessor sub medint()
med_with_default => $MediumInteger,
};
# After using ConstrainedAccessor, actually define the class attributes.
use Class::Tiny qw(medint regular), {
med_with_default => 12,
};
If you don't want to use Type::Tiny or one of the other type systems listed above, you can create your own constraints as two-element arrayrefs. Example:
use Class::Tiny::ConstrainedAccessor
'field' => [ \&checker_sub, \&message_sub ];
checker_sub
and message_sub
are used as follows to check $value
:
checker_sub($value) or die get_message($value);
Therefore, checker_sub
must return truthy if $_[0]
passes the constraint,
or else falsy. get_message
must return something that can be passed to
die()
, when given a $_[0]
that has failed the constraint.
If your profile ever tells you that constraint-checks are on the critical path, try custom constraints. They may give you more control or opportunity for optimization than general-purpose type systems.
Creates the accessors you have requested. Constraints can be passed as a list or hashref of variable/constraint pairs. Basic usage:
# Constraints are passed as a list of pairs
use Class::Tiny::ConstrainedAccessor
name => constraint
[, name2 => constraint ...]; # ... any number of name=>constraint pairs
# Constraints are passed as a hashref
use Class::Tiny::ConstrainedAccessor {
name => constraint,
[, name2 => constraint ...]; # ... any number of name=>constraint pairs
};
This also creates a BUILD() subroutine to check the
constructor parameters, if a BUILD()
doesn't already exist.
If a BUILD()
does exist (e.g., you said use subs 'BUILD';
), this package
will create the same function, taking the same parameters as BUILD()
would,
but call it _check_all_constraints()
. You can call this checker from your
own BUILD()
if you want to.
To specify options, pass an arrayref as the first argument on the `use` line. This is because a hashref carries attributes and constraints. For example:
use Class::Tiny::ConstrainedAccessor [ OPTION=>value ],
name => constraint ...;
Valid options are:
-
NOBUILD
If
NOBUILD => 1
is given, the constructor-parameter-checker is created as_check_all_constraints
regardless of whetherBUILD()
exists or not. Example:package MyClass; use Class::Tiny::ConstrainedAccessor [NOBUILD => 1], foo => SomeConstraint; # Now $object->_check_all_constraints($args) exists, but not BUILD().
Created by Christopher White, <cxwembedded at gmail.com>
. Thanks to
Toby Inkster (TOBYINK) and Ivan Butorin (FISHBONE) for code contributions.
Please report any bugs or feature requests through the GitHub Issues interface at https://github.com/cxw42/Class-Tiny-ConstrainedAccessor/issues. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
You can find documentation for this module with the perldoc command.
perldoc Class::Tiny::ConstrainedAccessor
You can also look for information at:
-
GitHub (report bugs here)
-
MetaCPAN
Copyright 2019 Christopher White and contributors.
This program is free software; you can redistribute it and/or modify it under the terms of the the Apache License (2.0). You may obtain a copy of the full license at:
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.