Reputation: 6042
I have a situation where I expect variables to be passed to me as strings or numbers.
i.e.
sub foo {
# These can be either strings or numbers
my ($bar, $var, $star) = @_;
# I need to check to see if $bar is the number 0 (zero)
if ($bar == 0) {
# Do super magic with it
}
}
Unfortunately Perl tries to do the super magic on $bar
when it contains a string.
How can I tell Perl to do super magic on $bar
if and only if it is the number 0 (zero)?
I understand Perl fundamentally interprets based on context, which is the underlying problem here. A possible solution to this problem is to use regex, which is fine, but I wanted to know if there was another more "straight-forward" solution.
Thanks in advance.
Upvotes: 1
Views: 279
Reputation: 4311
Between looks_like_number
and numerical comparisons, you can get quite good results quite easily:
use Scalar::Util qw(looks_like_number);
use Test::More tests => 7;
sub is_numerically_zero {
my ($string) = @_;
return (looks_like_number($string) and $string == 0);
}
for my $string (qw(0 0.0 0e0), ' 0 ') {
ok(is_numerically_zero($string));
}
for my $string (qw(duckies 123), '') {
ok(not is_numerically_zero($string));
}
This assumes you don't want to just match the literal string '0'
.
Upvotes: 0
Reputation: 385829
It depends on what you mean by "number 0". Obviously, you include the one character string 0
is zero. But what you about three character string 0.0
?
If you just want to match the one character string 0
, use
if ($bar eq '0') {
...
}
If you want to match what Perl considers number zero, use
use Scalar::Util qw( looks_like_number );
if (looks_like_number($bar) && $bar == 0) {
...
}
Upvotes: 2
Reputation: 54333
I'd personally go with what @Disco3's comment said.
if ($bar eq 0) { ... }
This works for $bar = 0
, $bar = 'foo'
and $bar = 123
giving the expected result.
Here's a fun fact, though:
use Benchmark qw(cmpthese);
my $bar = '0';
cmpthese(-1, {
'quoted' => sub { $bar eq '0' },
'unquoted' => sub { $bar eq 0 },
'regex' => sub { $bar =~ m/^0$/ },
});
Benchmarking these three solutions tells us that the unquoted 0
is the fastest way to do it.
Rate regex quoted unquoted
regex 4504851/s -- -70% -76%
quoted 15199885/s 237% -- -19%
unquoted 18828298/s 318% 24% --
Upvotes: 4