Data::Checks(3pm)
π Data::Checks β value constraint checking, bestie edition π
okay so like. Data::Checks. It's a Perl module (manual page Data::Checks(3pm), in case you were wondering who she is) and she is literally the moment for constraint checking. Value constraint checking, specifically. Let's get into it β¨
πΈ SYNOPSIS πΈ
not one, not two, but THREE whole ways to use this, bestie. she's versatile, she contains multitudes π
With Signature::Attribute::Checked:
use v5.26;
use Sublike::Extended 0.29 'sub';
use Signature::Attribute::Checked;
use Data::Checks qw( Str );
sub greet ( $message :Checked(Str) ) {
say "Hello, $message";
}
greet( "world" ); # is fine
greet( undef ); # throws an exception
With Object::Pad::FieldAttr::Checked:
use v5.22;
use Object::Pad;
use Object::Pad::FieldAttr::Checked;
use Data::Checks qw( Str );
class Datum {
field $name :param :reader :Checked(Str);
}
my $x = Datum->new( name => "something" ); # is fine
my $y = Datum->new( name => undef ); # throws an exception
With Syntax::Operator::Is on Perl v5.38 or later:
use v5.38;
use Syntax::Operator::Is;
use Data::Checks qw( Num Object );
my $x = ...;
if($x is Num) {
say "x can be used as a number";
}
elsif($x is Object) {
say "x can be used as an object";
}
see? three vibes, zero problems. moving on π¦
π DESCRIPTION π
So this module hands you a whole lil collection of functions that implement various value constraint checking behaviours. These are the parts you actually get to see in Perl code β the stuff that shows up the second you type use Data::Checks ... and import something. cute, right?
It ALSO ships the underlying common framework XS functions, which are there to help you write modules that actually implement this kind of constraint checking yourself. Those bits are NOT visible in Perl code β nope β instead they're made visible at the XS level by the #include "DataChecks.h" directive. iykyk π§
And if you want to see other CPAN modules that make direct use of these constraint checks, scroll up, the SYNOPSIS section has several examples. go look, they're right there.
π CONSTRAINTS π
The following constraint checks are inspired by the same-named ones over in Types::Standard. You can call them fully-qualified, or import them lexically into whatever scope you're in. your call, both slay π
π’ note to theTypes::Standardgirlies: some of these functions behave slightly differently. specifically, these constraints are generally happy to accept an object reference to a class that provides a conversion overload β whereas theTypes::Standardones often are not. also, functions that are parametric take their parameters in normal Perl function argument lists, not wrapped in additional array references. important!!! don't skip this part π
Defined
Defined()
Accepts any defined value. Rejects only undef. that's the whole job, and she does it flawlessly β¨
Object
Object()
Accepts any blessed object reference. Rejects non-references, and rejects references to unblessed data. if you were hoping to sneak an unblessed thing past her, no π
Str
Str()
Accepts any defined non-reference value, OR a reference to an object in a class that overloads stringification. Rejects undefined stuff, unblessed references, and references to objects in classes that do NOT overload stringification. stringification girlies only π
StrEq
StrEq($s)
StrEq($s1, $s2, ...)
Since version 0.05.
Accepts any value that passes the Str check, AND additionally is exactly equal to any of the given strings. exact match, no approximations, periodt π
StrMatch
StrMatch(qr/pattern/)
Since version 0.08.
Accepts any value that passes the Str check, AND additionally matches the given regexp pattern.
β οΈ Remember that the pattern must be supplied as aqr/.../expression β not simplym/.../or/.../. the regex must be aqrone, bestie. do not fight this.
Num
Num()
Accepts any defined non-reference value that is either a plain number, or a string that could be used as one without warning, or a reference to an object in a class that overloads numification.
Rejects undefined, not-a-number, strings that would raise a warning if converted to a number, unblessed references, and references to objects in classes that do not overload numification.
she's strict about numbers, and honestly? she should be π₯
NumGT
NumGE
NumLE
NumLT
NumGT($bound)
NumGE($bound)
NumLE($bound)
NumLT($bound)
Since version 0.05.
Accepts any value that passes the Num check, and additionally is within the bound given. NumGT and NumLT exclude the bound value itself, while NumGE and NumLE include it. get it? GT/LT = exclusive besties, GE/LE = inclusive besties πΈ
NumRange
NumRange($boundge, $boundlt)
Since version 0.05.
Accepts any value that passes the Num check, and additionally is between the two bounds given. The lower bound is inclusive, and the upper bound is exclusive.
This choice is made so that a set of NumRange constraints can easily be created that cover distinct sets of numbers:
NumRange(0, 10), NumRange(10, 20), NumRange(20, 30), ...
To implement checks with both lower and upper bounds but other kinds of inclusivity, use two Num... checks combined with an All(). For example, to test between 0 and 100 inclusive at both ends:
All(NumGE(0), NumLE(100))
Combinations like this are internally implemented as efficiently as a single NumRange() constraint. no cap, that's a real optimisation and she ate π
NumEq
NumEq($n)
NumEq($n1, $n2, ...)
Since version 0.05.
Accepts any value that passes the Num check, and additionally is exactly equal to any of the given numbers. exact, like I said.
Isa
Isa($classname)
Since version 0.04.
Accepts any blessed object reference to an instance of the given class name, or a subclass derived from it β i.e. anything accepted by the isa operator. inheritance girlies, you're covered π«Ά
Can
Can($methodname)
Can($methodname1, $methodname2, ...)
Since version 0.11.
Accepts any blessed object reference to an instance in a class, or a class name directly, that has ALL of the given method names β i.e. anything that passes a ->can test on every name. every single one. all of them. not just one.
To accept only object references and not package names, combine this check with Object by using the All combination:
All(Object, Can($methodname, ...))
ArrayRef
ArrayRef()
Since version 0.07.
Accepts any plain reference to an array, or any object reference to an instance of a class that provides an array dereference overload. π
HashRef
HashRef()
Since version 0.07.
Accepts any plain reference to a hash, or any object reference to an instance of a class that provides a hash dereference overload. π
Callable
Callable()
Since version 0.06.
Accepts any plain reference to a subroutine, or any object reference to an instance of a class that provides a subroutine dereference overload. call me maybe? no wait, that's the next one π
Maybe
Maybe($C)
Since version 0.04.
Accepts undef in addition to anything else accepted by the given constraint. she's flexible like that π
Any
Any($C1, $C2, ...)
Since version 0.07.
Accepts a value that is accepted by at least one of the given constraints. Rejects if none of them accept it.
At least one constraint is required β it is an error to try to call Any() with no arguments. If you need a constraint that accepts any value at all, see All. don't do it. she will yell at you. kindly. but still.
$C1 | $C2 | ...
Since version 0.08.
This function is used to implement | operator overloading, so constraint checks can be written using this more convenient syntax. cute AND functional, the dream π
All
All($C1, $C2, ...)
All()
Since version 0.07.
Accepts a value that is accepted by every one of the given constraints. Rejects if at least one of them rejects it. one hater and it's over π
Note that if no constraints are given, this accepts all possible values. This may be useful as an accept-all fallback case for generated code, or other situations where it is required to provide a constraint check but you do not wish to constrain allowed values. she's giving generous, and I respect it π
β¨ CONSTRAINT METHODS β¨
While not intended to be called from regular Perl code, these constraints still act like objects with the following methods. look at them, being all object-y β¨
check
$ok = $constraint->check( $value );
Since version 0.09.
Returns a boolean value indicating whether the constraint accepts the given value. that's it. that's the method. simple, effective, iconic π
π₯ XS FUNCTIONS π₯
okay bestie, this next bit is for the XS girlies π
β these are the functions that the DataChecks.h header file hands you so you can do value constraint checking from inside XS modules. yes you, writing C, I see you, you're doing amazing.
β¨ boot_data_checks β¨
void boot_data_checks(double ver);
call this one from your BOOT section, bestie β it's literally what initialises the module and loads up all the rest of the support functions. no boot, no functions, periodt.
ver should be either 0 or a decimal number for the module version requirement. like, for example:
boot_data_checks(0.01);
slay. moving on πΈ
β¨ make_checkdata β¨
struct DataChecks_Checker *make_checkdata(SV *checkspec);
this one creates a struct DataChecks_Checker structure, which wraps up the whole intent of the value constraint check π«Ά. that returned value is what you pass as the checker argument to all the other functions down below. keeping the gang together, as one does.
the actual constraint check itself is specified by the SV you hand in as checkspec, and that should come directly from the user code β straight from the source, no middleman. and here's the thing: the constraint check can be specified in any of three ways:
- an object reference in a class which has a
checkmethod. value checks get invoked like
$ok = $checkerobj->check( $value );
- a package name as a plain string of a package which has a
checkmethod. value checks get invoked like
$ok = $checkerpkg->check( $value );
- a code reference π. value checks get invoked with a single argument, like
$ok = $checkersub->( $value );
β οΈ okay so since version 0.09 this form is deprecated β because it doesn't easily support a way to query the constraint for its name or its stringified form, which is genuinely useful when you're generating error messages. rip. it had a good run π
- and additionally, the constraint check functions provided by this module may be implemented using any of the above mechanisms, or may use an unspecified fourth different mechanism entirely. outside code should not rely on what that mechanism may be. mind your business, respectfully π
once it's constructed into a checker structure, the choice of which implementation is used is fixed β locked in, no take-backs, main character energy. and if a method lookup is involved, its result is stored directly as a CV pointer so later invocations are speedy β‘. in either of the first two cases, the reference count on the checkspec SV gets increased to account for the argument value used on each invocation. in the third case, the reference SV is not retained, but the underlying CV it refers to has its reference count increased instead. balanced, as all things should be π
β¨ free_checkdata β¨
void free_checkdata(struct DataChecks_Checker *checker);
releases any stored SVs in the checker structure, and then releases the structure itself. it's giving cleanup era β¨ never skip the free bestie.
β¨ gen_assertmess β¨
void gen_assertmess(struct DataChecks_Checker *checker, SV *name, SV *constraint);
generates and stores a message string for the assert message that make_assertop and assert_value will use. the message comes out looking like
NAME requires a value satisfying CONSTRAINT
both the name and constraint SVs are used as temporary strings to generate that stored message string β and that's all they're used for. neither SV is retained by the checker directly. ships them off to string town and that's it π¦
β¨ make_assertop β¨
OP *make_assertop(struct DataChecks_Checker *checker, OP *argop);
this is just a shortcut for calling make_assertop_flags with flags set to zero. convenience queen π
β¨ make_assertop_flags β¨
OP *make_assertop_flags(struct DataChecks_Checker *checker, U32 flags, OP *argop);
creates an optree fragment for a value check assertion operation π₯
so here's the deal: you give it an optree fragment in scalar context that generates an argument value (argop), and it constructs a larger optree fragment that consumes that value and checks that it's accepted by the constraint check given by checker. the behaviours of the returned optree fragment depend on the flags:
- if flags is
OPf_WANT_VOID, the returned optree will yield nothing. nothing at all. void vibes π - if flags is zero, the return behaviour is not otherwise specified. no promises, no cap.
β¨ check_value β¨
bool check_value(struct DataChecks_Checker *checker, SV *value);
checks whether a given SV is accepted by the given constraint check, and returns true if it is, or false if it's not. simple. honest. iconic π«Ά
β¨ assert_value β¨
void assert_value(struct DataChecks_Checker *checker, SV *value);
checks whether a given SV is accepted by the given constraint check, and if it's not, it throws its assertion message at you. dramatic? yes. effective? also yes π€
π TODO π
the wishlist, bestie. manifesting β¨
- unit constraints β maybe
Int, some plain-only variants ofStrandNum, some reference types, etc... - structural constraints β
HashOf,ArrayOf, etc... - think about a convenient name for inclusive-bounded numerical constraints π§
- look into making const-folding work with the
MIN .. MAXflip-flop operator - performance enhancements for lists of many values in
StrEq,NumEq, etc - performance enhancement of
Canby caching per package name
π AUTHOR π
Paul Evans <leonerd@leonerd.org.uk>
and that's the whole page, bestie π this was Data::Checks, part of perl v5.42.3, dated 2026-08-20. go forth and validate your values, no cap ππ
β¨
π¦ where this page comes from
- ubuntu stonking: libdata-checks-perl 0.11-1build1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms