http://www.perlmonks.org?node_id=852472


in reply to Re: Numification of strings
in thread Numification of strings

The atoi() function is a truly ancient thing. People were hunting dinner with spears when this thing first appeared, ...way before C. In C if you "abuse" this, there aren't any warnings. It is the user's responsibility to check the input values before calling atoi(). Some cases and normal ways to check for this are shown below.

#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *digits="0123456789"; char x[] = "2abc"; int result = atoi(x); printf ("case a) string %s is %d as decimal\n",x,result); if (strlen(x) == 0 || (strspn(x,digits) != strlen(x))) printf ("case b) %s is NOT a simple positive integer!\n" " there are either no digits or non-digits\n", x); char y[] = ""; int result_y = atoi(y); printf ("case c) a null string results in %d\n",result_y); return 0; } /* prints: case a) string 2abc is 2 as decimal case b) 2abc is NOT a simple positive integer! there are either no digits or non-digits case c) a null string results in 0 */
Perl is more generous and gives warnings if they are enabled. This will give a warning:
#!/usr/bin/perl -w use strict; my $a = "23B"; $a +=0; print $a;
You can check yourself if \D exists in string or if null string. Otherwise Perl will do the "best that it can".

Also of note is that in Perl, everything is a string a string that looks like a number is still a string until used in a numeric context. Consider this:

my $x = "00012"; print "$x\n"; $x+=0; print "$x\n"; ##prints #00012 #12
This is a "trick" that I sometimes use to delete leading zeroes.

Replies are listed 'Best First'.
Re^3: Numification of strings
by morgon (Priest) on Aug 02, 2010 at 18:01 UTC
    in Perl, everything is a string until used in a numeric context

    I don't think that is true.

    In your example you put quotation-marks around the value, so little surprise that you end up with a string...

    Consider this:

    use Devel::Peek; my $a = "1"; my $b = 2; print Dump($a); print Dump($b);
    This produces:

    SV = PV(0x98c9700) at 0x98ea3f8 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) PV = 0x98e6368 "1"\0 CUR = 1 LEN = 4 SV = IV(0x98ea474) at 0x98ea478 REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 2
    As you can see $a is a string "PV", while $b is an int "IV", even thought it was never used in an numeric context.
      "As you can see $a is a string "PV", while $b is an int "IV", even thought it was never used in an numeric context."

      If you mean what I think you mean -- that $b is an int BECAUSE it was never used in a numeric content -- I think you're wrong, morgon: $b IS an IV, because it was instantiated that way... as an integer, without quotes that would have made it a string.

      Update: Maybe I have the code tags right... at last.

        If you mean what I think you mean ...

        :-)

        I meant to disprove the theory that a value becomes an int only after being used in a numeric context by showing an example in which a value is only instantiated (and never used in a numeric context), yet still is numeric.

        Or less convoluted: I probably meant what you said.

      I updated my post above:
      re: Also of note is that in Perl, a string that looks like a number is still a string until used in a numeric context. Feel free to suggest alternate wording for this sentence.

      These leading zero situations can happen when reading DB files of various formats, say from a split() or whatever.