ultranerds has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm trying to figure this one out. Lets say we have this code:

$field = "abc"; if ($field > 0) { print "its a number" }


..then that doesn't print anything (as you would expect) ... but changing the string to "1abc" , returns true!

$field = "1abc"; if ($field > 0) { print "its a number" }
Whats the reason for this?

I know I could just use a regex to do it - but would just like to know the reason for it returning "true", even when the string obviously isn't a number =)

TIA

Andy

Replies are listed 'Best First'.
Re: Question re numbers and strings
by moritz (Cardinal) on Jan 13, 2011 at 08:57 UTC

    When you use a variable as a number, Perl tries hard to make it a number if it's not stored as a number internally. In Perl it's the operator that provides the context, and the data is transformed to fit to the operation.

    In the case of "1abc" the result is 1, plus a warning (if you have warnings enabled, as I strongly recommend). So it is indeed a number, if viewed as one.

    The test you might want to use instead is implemented in Scalar::Util::looks_like_number

      Hi,

      Thanks for the reply guys - thats sheds some light on the matter :)

      I think what I will do, is just use a regex for now then:

      $var =~ /^[1-9]\d*$/

      (the first bit is just to make sure its over 0 :))

      Thanks again

      Andy
        Just a tangential word of caution, Andy; quoting (determining interpolation) matters:
        C:>perl -e "my $var = '0x8';if ($var =~ /^[1-9]\d*$/) {print 'num' } e +lse {print 'not a num';}" not a num

        But

        C:>perl -e "my $var = 0x8;if ($var =~ /^[1-9]\d*$/) {print 'num' } els +e {print 'not a num';}" num
Re: Question re numbers and strings
by cdarke (Prior) on Jan 13, 2011 at 08:57 UTC
    In a word: atoi. You are using the numeric comparison operator >, so perl will try it's best to interpret the value as a number. For string comparisons you should use gt. The exact conversion on different platforms might vary depending on the implementation of the C run-time library routine atoi (ascii-to-int).
Re: Question re numbers and strings
by syphilis (Archbishop) on Jan 13, 2011 at 09:10 UTC
    The string "abc", evaluates to 0 in numeric context - which is *not* greater than 0.
    The string "1abc" evaluates to 1 in numeric context - which *is* greater than 0.
    It's the use of the ">" operator that's forcing the strings to be evaluated numerically.

    Cheers,
    Rob
Re: Question re numbers and strings
by Anonymous Monk on Jan 13, 2011 at 08:54 UTC
    If you treat it like a number, its a number
    $ perl -le " $f = q!1asdf!; print $f; $f++; print $f; " 1asdf 2
    See perldoc perlnumber
Re: Question re numbers and strings
by pat_mc (Pilgrim) on Jan 13, 2011 at 09:05 UTC
    Clearly, Perl is trying to interpret as much of the string as a number as it can. For that reason, the following will also work:
    my $field = 2; print "A number!", $field + 1 if ( $field > 1);
    So despite the warning that $field is not numerical Perl does try to read the actual numerical value assigned.

    Not sure if this is any help.

    Pat
Re: Question re numbers and strings
by locked_user sundialsvc4 (Abbot) on Jan 13, 2011 at 12:58 UTC

    “Typeless” languages can be both a blessing and a curse...

      For example, consider:

      my $seconds = $hourIndex * '60 minutes/hour' * '60 seconds/minute';
Re: Question re numbers and strings
by ikegami (Patriarch) on Jan 13, 2011 at 17:20 UTC