Perl - Is this a bug with looks_like_number, or am I being a stupid person?

perl

Solution

It's a bug that was fixed in Scalar::Util 1.20. ("Handle overloaded and tied values" in the `Changes` file.)

The XS version of `looks_like_number` failed to handle magical arguments properly. Magic is what allows code to be called when certain operations are performed on a variable (such as fetching its value).

Solutions:

- Upgrade to Scalar::Util 1.20 or higher.

- Delete the compiled component of your Scalar::Util to force the use of the Pure Perl implementation which doesn't suffer from this problem.

- Use `looks_like_number("$1")` which creates a non-magical copy of `$1` with the right value.

1.19:

int
looks_like_number(sv)
        SV *sv
PROTOTYPE: $
CODE:
#if (PERL_VERSION < 8) || (PERL_VERSION == 8 && PERL_SUBVERSION <5)
  if (SvPOK(sv) || SvPOKp(sv)) {
    RETVAL = looks_like_number(sv);
  }
  else {
    RETVAL = SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK);
  }
#else
  RETVAL = looks_like_number(sv);
#endif
OUTPUT:
 RETVAL

1.21:

int
looks_like_number(sv)
    SV *sv
PROTOTYPE: $
CODE:
  SV *tempsv;
  if (SvAMAGIC(sv) && (tempsv = AMG_CALLun(sv, numer))) {
    sv = tempsv;
  }
  else if (SvMAGICAL(sv)) {
      SvGETMAGIC(sv);
  }
#if (PERL_VERSION < 8) || (PERL_VERSION == 8 && PERL_SUBVERSION <5)
  if (SvPOK(sv) || SvPOKp(sv)) {
    RETVAL = looks_like_number(sv);
  }
  else {
    RETVAL = SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK);
  }
#else
  RETVAL = looks_like_number(sv);
#endif
OUTPUT:
  RETVAL

Try this:

what_the_fudge("foo 123 bar");
what_the_fudge("foo baz bar");
what_the_fudge("foo 123 bar");

sub what_the_fudge {
    my $string = shift;

I haven't actually tried it, but you should get

Version of Scalar::Util: 1.19
doesnt look like a number
looks like a number
doesnt look like a number

Problem

This code: ``` #!/usr/bin/perl -w use strict; use Scalar::Util qw(looks_like_number); sub what_the_fudge { my $string = "foo 123 bar"; if ($string =~ /foo (.+) bar/) { if (looks_like_number($1)) { print "$1 looks like a number\n"; } else { print "$1 doesnt look like a number\n"; } } } &what_the_fudge; &what_the_fudge; &what_the_fudge; ``` Displays this: ``` 123 doesnt look like a number 123 looks like a number 123 looks like a number ``` Why does it fail to recognize it as a number the first time? =( This baffles me. Some information about my environment: OS: OSX 10.6.8 `perl -e 'use Scalar::Util; print "$Scalar::Util::VERSION\n"'` --> 1.19 `perl -v` --> This is perl, v5.10.0 built for darwin-thread-multi-2level (with 2 registered patches, see perl -V for more detail)

Original source