[ic] [interchange] Add numeric ordercheck
Jon Jensen
jon at endpoint.com
Fri Mar 26 03:10:46 UTC 2010
On Thu, 25 Mar 2010, Mike Heins wrote:
> I think perhaps I would prefer:
>
> use Scalar::Util qw/looks_like_number/;
Well, I was about to commit this, but read the docs for it and saw it
allows "Inf" and "Infinity" as numbers. That seems unacceptable since it's
a narrow Perl definition that will fail in SQL, in numbers going to
payment gateways, etc. It also accepts exponents such as 1e20, which is
standard floating-point, but not a standard numeric.
It's too bad, because I like the idea of using the fast built-in for this.
I checked out what Regexp::Common offers, and its 'decimal' test allows -.
and +. through, which seems broken to me.
Both of those allow through 05, 005, etc., which is tolerated by e.g.
Postgres but in at least Perl and JavaScript may be interpreted as octal.
I prohibited it in my new routine.
I put together an expanded test that compares the three routines I've been
looking at. Let me know what you all think, and if there are any other
test cases we should be considering.
Jon
use strict;
use warnings;
no warnings 'qw';
use Scalar::Util qw/looks_like_number/;
use Regexp::Common;
my @tests = qw/
1
0.5
-1
-1.0
-1.0000
-0.5
+0.5
+0.
+1.
+.5
-.5
-.
+.
-2.1.1
+.1.1
01
01.6
005
009
Inf
Infinity
Infoobar
1e20
1e+20
1e-20
1.62e8
1.
.1
1.1.1
+1
1,0
/;
my %routines = (
looks_like_number => sub { looks_like_number($_[0]) },
custom_regex => sub { defined($_[0]) and $_[0] =~ /\A[-+]?(?:0\.\d*|[1-9]\d*(?:\.\d*)?|(?:[1-9]\d*|)\.\d+)?\z/ },
'Regexp::Common decimal' => sub { defined($_[0]) and $_[0] =~ /\A$RE{num}{decimal}\z/ },
);
for my $routine (sort keys %routines) {
print "\n$routine:\n";
for (@tests) {
my $result = $routines{$routine}->($_) ? 'true' : 'false';
printf "\ttesting %-20s: %s\n", "'$_'", $result;
}
}
--
Jon Jensen
End Point Corporation
http://www.endpoint.com/
More information about the interchange-users
mailing list