Ashutosh Arya
Ashutosh Arya

Reputation: 1168

Behavior of Scalar::Util::looks_like_number in Perl

I am trying to find out if an input is number or string. I came across looks_like_number and cannot understand the values it returns.

use warnings;
use Scalar::Util qw(looks_like_number);

my $name = 11;
print looks_like_number ($name);

This code prints 1 if $name contains a string and a static number if $name contains an integer (i.e. 4352 for each integer).

I am using Perl on Windows.

Upvotes: 8

Views: 12030

Answers (3)

LeoNerd
LeoNerd

Reputation: 8532

Don't rely on the exact numerical value. This is an abstraction leak, which the latest version of Scalar::Util (1.39) fixes. What is important is simply the truth of the result, not its exact numerical value.

See bug https://rt.cpan.org/Ticket/Display.html?id=94806

Upvotes: 7

ikegami
ikegami

Reputation: 386501

You forgot to ask a question! Here are two possibilities.

Why doesn't it always return the same value for true?

Why not? It returns a true value as documented. It makes no difference which true value it is.

What is the value returned?

If the scalar contains a string, it uses grok_number which has specific document return values.

The type of the number is returned (0 if unrecognised), otherwise it is a bit-ORed combination of IS_NUMBER_IN_UV, IS_NUMBER_GREATER_THAN_UV_MAX, IS_NUMBER_NOT_INT, IS_NUMBER_NEG, IS_NUMBER_INFINITY, IS_NUMBER_NAN (defined in perl.h).

Otherwise, it uses

SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK)

You can't tell which of the two was used, so you can't ascribe meaning to the value, which is why it's undocumented.

Upvotes: 20

simbabque
simbabque

Reputation: 54371

This is what the documentation says:

looks_like_number EXPR

Returns true if perl thinks EXPR is a number. See "looks_like_number" in perlapi.

The link to perlapi in this quote is not really helping us a lot unfortunately:

Test if the content of an SV looks like a number (or is a number). Inf and Infinity are treated as numbers (so will not issue a non-numeric warning), even if your atof() doesn't grok them. Get-magic is ignored.

I32   looks_like_number(SV *const sv)

In my case, your code will return an integer that is not 0, which is true.

  • I got 4352 when I used 11.
  • When I used '11' I got 1.

All of these are true, so that works.

  • When I put 'test' or 'foobar' I got 0, which is not true.
  • I never got a 1 for anything that did not look like a number.
  • I tried '1e1' and it printed 4, which is a true value, and the input looked like a number in scientific notation.

So, I'd say it always returns something true if Perl thinks the input looks like a number, though I do not know what exactly that true value represents. I cannot confirm that it also returns true with a name.

Upvotes: 6

Related Questions