File Coverage

blib/lib/Scalar/Type.pm
Criterion Covered Total %
statement 40 42 95.2
branch 26 30 86.6
condition 4 6 66.6
subroutine 15 15 100.0
pod 6 6 100.0
total 91 99 91.9


line stmt bran cond sub pod time code
1             package Scalar::Type;
2              
3 3     3   259490 use strict;
  3         29  
  3         97  
4 3     3   15 use warnings;
  3         6  
  3         135  
5              
6             our $BOOL_SUPPORTED;
7              
8 3     3   141 BEGIN { $BOOL_SUPPORTED = ($] >= 5.035007) }
9 96     96 1 851 sub bool_supported { $BOOL_SUPPORTED; }
10              
11 3     3   2148 use if bool_supported(), qw(builtin isbool);
  3         68  
  3         13  
12              
13 3     3   136 use Carp qw(croak);
  3         5  
  3         173  
14 3     3   16 use Config;
  3         6  
  3         195  
15              
16             our $VERSION = '0.3.1';
17              
18             require XSLoader;
19             XSLoader::load(__PACKAGE__, $VERSION);
20              
21 3     3   17 use Scalar::Util qw(blessed);
  3         5  
  3         126  
22              
23 3     3   51 use base qw(Exporter);
  3         8  
  3         2177  
24              
25             =head1 NAME
26              
27             Scalar::Type
28              
29             =head1 DESCRIPTION
30              
31             Figure out what type a scalar is
32              
33             =head1 SYNOPSIS
34              
35             use Scalar::Type qw(is_number);
36              
37             if(is_number(2)) {
38             # yep, 2 is a number
39             # it is_integer too
40             }
41              
42             if(is_number("2")) {
43             # no, "2" is a string
44             }
45              
46             =head1 OVERVIEW
47              
48             Perl scalars can be either strings or numbers, and normally you don't really
49             care which is which as it will do all the necessary type conversions automagically.
50             This means that you can perform numeric operations on strings and provided that they
51             B a number you'll get a sensible result:
52              
53             my $string = "4";
54             my $number = 1;
55             my $result = $string + $number; # 5
56              
57             But in some rare cases, generally when you are serialising data, the difference
58             matters. This package provides some useful functions to help you figure out what's
59             what. The following functions are available. None of them are exported by default.
60             If you want them all, export ':all':
61              
62             use Scalar::Type qw(:all);
63              
64             and if you just want the 'is_*' functions you can get them all in one go:
65              
66             use Scalar::Type qw(is_*);
67              
68             For Reasons, C<:is_*> is equivalent.
69              
70             =cut
71              
72             our @EXPORT_OK = qw(
73             type sizeof is_integer is_number is_bool bool_supported
74             );
75             our %EXPORT_TAGS = (
76             all => \@EXPORT_OK,
77             'is_*' => [grep { /^is_/ } @EXPORT_OK]
78             );
79              
80             sub import {
81 3 100   3   23 __PACKAGE__->export_to_level(1, map { $_ eq 'is_*' ? ':is_*' : $_ } @_);
  7         4872  
82             }
83              
84             =head1 FUNCTIONS
85              
86             All of these functions require an argument. It is a fatal error to call
87             them without.
88              
89             =head2 type
90              
91             Returns the type of its argument.
92              
93             If the argument is a reference then it returns either
94             C (if it's an object),
95             or C<'REF_TO_'.ref($argument)>.
96              
97             If the argument is C then it returns C<'UNDEF'>.
98              
99             If you are using perl 5.35.7 or later and the argument is the result of a
100             comparison then it returns C<'BOOL'>.
101              
102             Otherwise it looks for the IOK or NOK flags on the underlying SV (see
103             L for the exact mechanics) and returns C or C
104             as appropriate. Finally, if neither of those are set it returns C.
105              
106             =head2 bool_supported
107              
108             Returns true if the C<'BOOL'> type is supported on this perl (ie if your
109             perl version is 5.35.7 or later) and false otherwise.
110              
111             =cut
112              
113             sub type {
114 99 100   99 1 25408 croak(__PACKAGE__."::type requires an argument") if($#_ == -1);
115 98         202 my $arg = shift;
116 98 50 33     437 return blessed($arg) ? blessed($arg) :
    100          
    100          
    100          
117             ref($arg) ? 'REF_TO_'.ref($arg) :
118             !defined($arg) ? 'UNDEF' :
119             (bool_supported && isbool($arg)) ? 'BOOL' :
120             _scalar_type($arg);
121             }
122              
123             =head2 sizeof
124              
125             Returns the size, in bytes, of the underlying storage for numeric types, and die()s for any other type.
126              
127             =cut
128              
129             sub sizeof {
130 4 100   4 1 8058 croak(__PACKAGE__."::sizeof requires an argument") if($#_ == -1);
131 3         8 my $arg = shift;
132 3         12 my $type = type($arg);
133 3 100       29 if($type eq 'INTEGER') {
    100          
134 1         97 return $Config{ivsize};
135             } elsif($type eq 'NUMBER') {
136 1         97 return $Config{nvsize};
137             } else {
138 1         6 croak(__PACKAGE__."::sizeof: '$arg' isn't numeric: ".type($arg)."\n");
139             }
140             }
141              
142             =head2 is_integer
143              
144             Returns true if its argument is an integer. Note that "1" is not an integer, it
145             is a string. 1 is an integer. 1.1 is obviously not an integer. 1.0 is also not
146             an integer, as it makes a different statement about precision - 1 is *exactly*
147             one, but 1.0 is only one to two significant figures.
148              
149             All integers are of course also numbers.
150              
151             =cut
152              
153             sub is_integer {
154 57 100   57 1 23309 croak(__PACKAGE__."::is_integer requires an argument") if($#_ == -1);
155 56 100       113 type(@_) eq 'INTEGER' ? 1 : 0;
156             }
157              
158             =head2 is_number
159              
160             Returns true if its argument is a number. "1" is not a number, it is a string.
161             1 is a number. 1.0 and 1.1 are numbers too.
162              
163             =cut
164              
165             sub is_number {
166 24 100   24 1 3427 croak(__PACKAGE__."::is_number requires an argument") if($#_ == -1);
167 23 100 100     48 is_integer(@_) || type(@_) eq 'NUMBER' ? 1 : 0;
168             }
169              
170             =head2 is_bool
171              
172             It is a fatal error to call this on perl versions earlier than 5.35.7.
173              
174             Returns true if its argument is a Boolean - ie, the result of a comparison.
175              
176             =cut
177              
178             sub is_bool {
179 1 50   1 1 75 croak(__PACKAGE__."::is_bool not supported on your perl") if(!bool_supported);
180 0 0         croak(__PACKAGE__."::is_bool requires an argument") if($#_ == -1);
181 0           type(@_) eq 'BOOL';
182             }
183              
184             =head1 GORY DETAILS
185              
186             =head2 PERL VARIABLE INTERNALS
187              
188             As far as Perl code is concerned scalars will present themselves as integers,
189             floats or strings on demand. Internally scalars are stored in a C structure,
190             called an SV (scalar value), which contains several slots. The important ones
191             for our purposes are:
192              
193             =over
194              
195             =item IV
196              
197             an integer value
198              
199             =item UV
200              
201             an unsigned integer value, only used for ints > MAXINT / 2.
202              
203             =item NV
204              
205             a numeric value (ie a float)
206              
207             =item PV
208              
209             a pointer value (ie a string)
210              
211             =back
212              
213             When a value is created one of those slots will be filled. As various
214             operations are done on a value the slot's contents may change, and other
215             slots may be filled.
216              
217             For example:
218              
219             my $foo = "4"; # fill $foo's PV slot, as "4" is a string
220              
221             my $bar = $foo + 1; # fill $bar's IV slot, as 4 + 1 is an int,
222             # and fill $foo's IV slot, as we had to figure
223             # out the numeric value of the string
224              
225             $foo = "lemon"; # fill $foo's PV slot, as "lemon" is a string
226              
227             That last operation immediately shows a problem. C<$foo>'s IV slot was
228             filled with the integer value C<4>, but the assignment of the string
229             C<"lemon"> only filled the PV slot. So what's in the IV slot? There's a
230             handy tool for that, L, which is distributed with perl.
231             Here's part of Devel::Peek's output:
232              
233             $ perl -MDevel::Peek -E 'my $foo = 4; $foo = "lemon"; Dump($foo);'
234             IV = 4
235             PV = 0x7fe6e6c04c90 "lemon"\0
236              
237             So how, then, does perl know that even thought there's a value in the IV
238             slot it shouldn't be used? Because once you've assigned C<"lemon"> to
239             the variable you can't get that C<4> to show itself ever again, at least
240             not from pure perl code.
241              
242             The SV also has a flags field, which I missed out above. (I've also missed
243             out some of the flags here, I'm only showing you the relevant ones):
244              
245             $ perl -MDevel::Peek -E 'my $foo = 4; $foo = "lemon"; Dump($foo);'
246             FLAGS = (POK)
247             IV = 4
248             PV = 0x7fe6e6c04c90 "lemon"\0
249              
250             The C flag means, as you might have guessed, that the C slot has
251             valid contents - in case you're wondering, the C slot there contains
252             a pointer to the memory address C<0x7fe6e6c04c90>, at which can be found
253             the word C.
254              
255             It's possible to have multiple flags set. That's the case in the second
256             line of code in the example. In that example a variable contains the
257             string C<"4">, so the C slot is filled and the C flag is set. We
258             then take the value of that variable, add 1, and assign the result to
259             another variable. Obviously adding 1 to a string is meaningless, so the
260             string has to first be converted to a number. That fills the C slot:
261              
262             $ perl -MDevel::Peek -E 'my $foo = "4"; my $bar = $foo + 1; Dump($foo);'
263             FLAGS = (IOK,POK)
264             IV = 4
265             PV = 0x7fd6e7d05210 "4"\0
266              
267             Notice that there are now two flags. C means that the C slot's
268             contents are valid, and C that the C slot's contents are valid.
269             Why do we need both slots in this case? Because a non-numeric string such
270             as C<"lemon"> is treated as the integer C<0> if you perform numeric
271             operations on it.
272              
273             All that I have said above about Cs also applies to Cs, and you
274             will sometimes come across a variable with both the C and C slots
275             filled, or even all three:
276              
277             $ perl -MDevel::Peek -E 'my $foo = 1e2; my $bar = $foo + 0; $bar = $foo . ""; Dump($foo)'
278             FLAGS = (IOK,NOK,POK)
279             IV = 100
280             NV = 100
281             PV = 0x7f9ee9d12790 "100"\0
282              
283             Finally, it's possible to have multiple flags set even though the slots
284             contain what looks (to a human) like different values:
285              
286             $ perl -MDevel::Peek -E 'my $foo = "007"; $foo + 0; Dump($foo)'
287             FLAGS = (IOK,POK)
288             IV = 7
289             PV = 0x7fcf425046c0 "007"\0
290              
291             That code initialises the variable to the string C<"007">, then uses it
292             in a numeric operation. That causes the string to be numified, the C
293             slot to be filled, and the C flag set. It should, of course, be clear
294             to any fan of classic literature that "007" and 7 are very different things.
295             "007" is not an integer.
296              
297             =head3 Booleans
298              
299             In perl 5.35.7 and later, Boolean values - ie the results of comparisons -
300             have some extra magic. As well as their value, which is either C<1> (true,
301             an integer) or C<''> (false, an empty string), they have a flag to indicate
302             their Booleanness. This is exposed via the C perl function
303             so we don't need to do XS voodoo to interrogate it.
304              
305             =head2 WHAT Scalar::Type DOES (at least in version 0.1.0)
306              
307             NB that this section documents an internal function that is not intended
308             for public use. The interface of C<_scalar_type> should be considered to
309             be unstable, not fit for human consumption, and subject to change without
310             notice. This documentation is correct as of version 0.1.0 but may not be
311             updated for future versions - its purpose is pedagogical only.
312              
313             The C functions are just wrappers around the C function. That
314             in turn delegates most of the work to a few lines of C code which grovel
315             around looking at the contents of the individual slots and flags. That
316             function isn't exported, but if you really want to call it directly it's
317             called C<_scalar_type> and will return one of four strings, C,
318             C, or C. It will return C even for a reference or
319             undef, which is why I said that the C function only *mostly* wraps
320             around it :-)
321              
322             The first thing that C<_scalar_type> does is look at the C flag.
323             If it's set, and the C flag is not set, the it returns C.
324             If C and C are set it stringifies the contents of the C slot,
325             compares to the contents of the C slot, and returns C if
326             they are the same, or C otherwise.
327              
328             The reason for jumping through those hoops is so that we can correctly
329             divine the type of C<"007"> in the last example above.
330              
331             If C isn't set we then look at C. That follows exactly the same
332             logic, looking also at C, and returning either C or C,
333             being careful about strings like C<"007.5">.
334              
335             If neither C nor C is set then we return C.
336              
337             And what about Cs? They are treated exactly the same as Cs, and a
338             variable with a valid C slot will have the B> flag set. It will
339             also have the C flag set, which we use to determine how to stringify
340             the number.
341              
342             =head1 SEE ALSO
343              
344             L in particular its C function.
345              
346             L if you have perl 5.35.7 or later.
347              
348             =head1 BUGS
349              
350             If you find any bugs please report them on Github, preferably with a test case.
351              
352             Integers that are specifed using exponential notation, such as if you say 1e2
353             instead of 100, are *not* internally treated as integers. The perl parser is
354             lazy and only bothers to convert them into an integer after you perform int-ish
355             operations on them, such as adding 0. Likewise if you add 0 to the thoroughly
356             non-numeric "100" perl will convert it to an integer. These edge cases are partly
357             why you almost certainly don't care about what this module does. If they irk
358             you, complain to p5p.
359              
360             =head1 FEEDBACK
361              
362             I welcome feedback about my code, especially constructive criticism.
363              
364             =head1 AUTHOR, COPYRIGHT and LICENCE
365              
366             Copyright 2021 David Cantrell EFE
367              
368             This software is free-as-in-speech software, and may be used,
369             distributed, and modified under the terms of either the GNU
370             General Public Licence version 2 or the Artistic Licence. It's
371             up to you which one you use. The full text of the licences can
372             be found in the files GPL2.txt and ARTISTIC.txt, respectively.
373              
374             =head1 CONSPIRACY
375              
376             This module is also free-as-in-mason software.
377              
378             =cut
379              
380             1;