File Coverage

blib/lib/MooseX/Types/StrictScalarTypes.pm
Criterion Covered Total %
statement 15 15 100.0
branch 1 2 50.0
condition n/a
subroutine 5 5 100.0
pod n/a
total 21 22 95.4


line stmt bran cond sub pod time code
1             package MooseX::Types::StrictScalarTypes;
2              
3 2     2   1065114 use strict;
  2         5  
  2         89  
4 2     2   13 use warnings;
  2         4  
  2         194  
5              
6             our $VERSION = '1.0.0';
7              
8 2     2   598 use Scalar::Type qw(bool_supported :is_*);
  2         4770  
  2         13  
9              
10 2 50   2   2084 use MooseX::Types -declare => [qw(StrictInt StrictNumber), (bool_supported() ? 'StrictBool' : ())];
  2         531825  
  2         13  
11 2     2   16083 use MooseX::Types::Moose qw(Value);
  2         16016  
  2         22  
12              
13             subtype StrictInt,
14             as Value,
15             where { is_integer($_) },
16             message { "value is not an integer (maybe it's a string that looks like an integer?)" };
17              
18             subtype StrictNumber,
19             as Value,
20             where { is_number($_) },
21             message { "value is not a number (maybe it's a string that looks like a number?)" };
22              
23             if(bool_supported) {
24             eval '
25             subtype StrictBool,
26             as Value,
27             where { is_bool($_) },
28             message { "value is not a Boolean (maybe it\'s a number that you\'re expecting to use as a Boolean?)" };
29             ';
30             }
31              
32             1;
33              
34             =head1 NAME
35              
36             MooseX::Types::StrictScalarTypes - strict Moose type constraints for integers, numbers, and Booleans
37              
38             =head1 SYNOPSIS
39              
40             package Foo;
41              
42             use Moose;
43             use MooseX::Types::StrictScalarTypes qw(StrictInt StrictNumber StrictBool);
44              
45             has integer => ( is => 'ro', isa => StrictInt );
46             has number => ( is => 'ro', isa => StrictNumber );
47             has boolean => ( is => 'ro', isa => StrictBool );
48              
49              
50             These will all throw exceptions:
51              
52             Foo->new(integer => 3.14); # because 3.14 is a float, not an int
53              
54             Foo->new(number => "3.14"); # that's a string, not a number
55              
56             Foo->new(boolean => 1); # that's an integer, not the result of a comparison
57              
58             And these will not:
59              
60             Foo->new(integer => 3);
61              
62             Foo->new(number => 3.14);
63              
64             Foo->new(boolean => 0 == 1);
65              
66             =head1 DESCRIPTION
67              
68             Perl scalars can be either strings or numbers, and normally you don't really
69             care which is which as it will do all the necessary type conversions automagically.
70              
71             But in some rare cases the difference matters. This package provides some
72             Moose type constraints to let you easily enforce stricter type checking than
73             what Moose can normally do with its builtin C<Int>, C<Number> and C<Bool> types.
74              
75             Internally it uses L<Scalar::Type> so see its documentation if you want to know
76             the gory details.
77              
78             =head1 LIMITATIONS
79              
80             The Boolean type is only available in perl 5.36 and higher. Attempting to use it
81             on an older perl is a fatal error. You can use C<Scalar::Type::bool_supported>
82             to easily check at run-time whether it will be available or not.
83              
84             =head1 TYPES
85              
86             =over
87              
88             =item StrictInt
89              
90             A type that only accepts integers. Floating point numbers such as C<3.0> and
91             strings like C<"3"> are not permitted.
92              
93             =item StrictNumber
94              
95             A type that only accepts numbers. Strings like C<"3"> are not permitted.
96              
97             =item StrictBool
98              
99             A type that only accepts Booleans, the result of a comparison. Numbers and strings
100             such as C<1> and C<""> are not permitted, but values like C<1 == 0> are.
101              
102             =back
103              
104             =head1 SEE ALSO
105              
106             L<Test2::Tools::Type> - similarly strict checking for your tests
107              
108             L<Scalar::Type>
109              
110             =head1 BUGS
111              
112             If you find any bugs please report them on Github, preferably with a test case.
113              
114             =head1 FEEDBACK
115              
116             I welcome feedback about my code, especially constructive criticism.
117              
118             =head1 AUTHOR, COPYRIGHT and LICENCE
119              
120             Copyright 2024 David Cantrell E<lt>F<david@cantrell.org.uk>E<gt>
121              
122             This software is free-as-in-speech software, and may be used,
123             distributed, and modified under the terms of either the GNU
124             General Public Licence version 2 or the Artistic Licence. It's
125             up to you which one you use. The full text of the licences can
126             be found in the files GPL2.txt and ARTISTIC.txt, respectively.
127              
128             =head1 CONSPIRACY
129              
130             This module is also free-as-in-mason software.