All data in Perl is a scalar or an array of scalars or a hash of scalars. Scalar variables may contain various kinds of singular data, such as numbers, strings, and references. In general, conversion from one form to another is transparent.
(A scalar may not contain multiple values, but may contain a reference to an array or hash containing multiple values.) Because of the automatic conversion of scalars, operations, and functions that return scalars don't need to care (and, in fact, can't care) whether the context is looking for a string or a number.
Scalars aren't necessarily one thing or another. There's no place to
declare a scalar variable to be of type ``string'', or of type ``number'',
or type ``filehandle'', or anything else. Perl is a contextually
polymorphic language whose scalars can be strings, numbers, or references
(which includes objects). While strings and numbers are considered pretty
much the same thing for nearly all purposes, references are strongly-typed
uncastable pointers with builtin reference-counting and destructor
invocation.
A scalar value is interpreted as
TRUE in the Boolean sense if it is not the null string or the number 0 (or its string equivalent, ``0''). The Boolean context is just a special kind of scalar context.
There are actually two varieties of null scalars: defined and undefined.
Undefined null scalars are returned when there is no real value for
something, such as when there was an error, or at end of file, or when you
refer to an uninitialized variable or element of an array. An undefined
null scalar may become defined the first time you use it as if it were
defined, but prior to that you can use the defined() operator
to determine whether the value is defined or not.
To find out whether a given string is a valid nonzero number, it's usually
enough to test it against both numeric 0 and also lexical ``0'' (although
this will cause -w noises). That's because strings that aren't numbers count as 0, just as
they do in awk:
if ($str == 0 && $str ne "0") {
warn "That doesn't look like a number";
}
That's usually preferable because otherwise you won't treat
IEEE notations like NaN or Infinity properly. At other times you might prefer to use a regular expression to
check whether data is numeric. See the perlre manpage
for details on regular expressions.
warn "has nondigits" if /\D/;
warn "not a whole number" unless /^\d+$/;
warn "not an integer" unless /^[+-]?\d+$/
warn "not a decimal number" unless /^[+-]?\d+\.?\d*$/
warn "not a C float"
unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
The length of an array is a scalar value. You may find the length of array
@days by evaluating $#days , as in csh. (Actually, it's not the length of the array, it's the subscript of the
last element, because there is (ordinarily) a 0th element.) Assigning to $#days changes the length of the array. Shortening an array by this method
destroys intervening values. Lengthening an array that was previously
shortened
NO LONGER recovers the values that were in those elements. (It used to in Perl 4, but
we had to break this to make sure destructors were called when expected.)
You can also gain some measure of efficiency by pre-extending an array that
is going to get big. (You can also extend an array by assigning to an
element that is off the end of the array.) You can truncate an array down
to nothing by assigning the null list () to it. The following are
equivalent:
@whatever = ();
$#whatever = -1;
If you evaluate a named array in a scalar context, it returns the length of the array. (Note that this is not true of lists, which return the last value, like the
C comma operator.) The following is always true:
scalar(@whatever) == $#whatever - $[ + 1;
Version 5 of Perl changed the semantics of $[ : files that don't set the value of $[ no longer need to worry about whether another file changed its value. (In
other words, use of $[ is deprecated.) So in general you can assume that
scalar(@whatever) == $#whatever + 1;
Some programmers choose to use an explicit conversion so nothing's left to
doubt:
$element_count = scalar(@whatever);
If you evaluate a hash in a scalar context, it returns a value which is
true if and only if the hash contains any key/value pairs. (If there are
any key/value pairs, the value returned is a string consisting of the
number of used buckets and the number of allocated buckets, separated by a
slash. This is pretty much useful only to find out whether Perl's (compiled
in) hashing algorithm is performing poorly on your data set. For example,
you stick 10,000 things in a hash, but evaluating %HASH in
scalar context reveals ``1/16'', which means only one out of sixteen
buckets has been touched, and presumably contains all 10,000 of your items.
This isn't supposed to happen.)
Source: Perl data types Copyright: Larry Wall, et al. |