Well, I can think of quite a few meanings of "is an integer".
- Fits in a Perl UV:
sub isUV {
my( $i )= @_;
return isIntVal($i) && $i == (0|$i);
}
- Fits in a Perl IV (no test provided)
- Fits in a Perl NV but has no fractional part:
sub isNVint {
my( $i )= @_;
return isIntVal($i) && $i == int($i);
}
- Is the (string) representation of an integer that may not fit into (1), (2), or (3):
sub isInt {
my( $i )= @_;
return $i =~ /^-?\d+\z/;
}
- A scalar that will result in (1), (2), or (3) w/o warning when used in a "numeric context":
sub isIntVal {
my( $i )= @_;
return $i =~ /^\s*[-+]?\d+\s*$/;
}
But (update) that doesn't cover "1.2e4", for example,
so you can also use (updated):
sub isIntVal2 {
my( $i )= @_;
my $warn= 0;
{
local( $^W )= 1;
# my $warn= 0;
local( $SIG{__WARN__} )= sub { $warn++ };
$i= 0+$i;
}
return ! $warn && int($i) == $i;
}
- A string that will result in literal (1), (2), or (3) w/o warning when used in Perl code (for example, with eval). This one has to allow for _ in the middle, "0x" or "0b" at the start, etc.
And, in particular, (4) has plenty of room for changes based on what you think should be allowed. And my test for (3) doesn't account for numbers that don't
accurately fit in an NV.
I really think that the best solution involves making the looks_like_number() C subroutine that Perl itself uses available to scripts.
-
tye
(but my friends call me "Tye")