How Perl converts strings to numbers

Any string in the Perl programming language can be used as a number. Here's an example:

▶ Run
#!/usr/bin/perl

my $str = 'Hello';

print $str + 100;

The program will display the number 100. String 'Hello' when used in arithmetic operations is the number 0. The number 0 plus 100 will 100 and that is what we will see on the screen. Often used the words "numerical context" to refer to what is the value of the operation is used as a number.

String 'Hello' in a numeric context it 0. But not all strings in Perl are zero.

If in the beginning of a line are digits, then the number becomes the sum of these numbers. Here's an example:

▶ Run
#!/usr/bin/perl

my $str = '23ASDF';

print $str + 0;

The program will display the number 23.

Here are a few examples, the string and the number in which it turns when used in a numeric context:

''          -> 0
'1.0ASDF'   -> 1
'1.2ADF'    -> 1.2
'0123ASDF'  -> 123
' 34ASDF'   -> 34
'0x13ABC'   -> 0
'0b10ABC'   -> 0
'1e+25ASDF' -> 1e+25
' +7ASDF'   -> 7
'-13ABC'    -> -13
'--13ABC'   -> 0
' 10 100'   -> 10

Here's a script that will display the same data:

▶ Run
#!/usr/bin/perl

use feature qw(say);

foreach my $str ('', '1.0ASDF', '1.2ADF', '0123ASDF', ' 34ASDF',  '0x13ABC', '0b10ABC', '1e+25ASDF', ' +7ASDF', '-13ABC', '--13ABC', ' 10 100') {
     say "'$str' -> " . ($str + 0);
}

use warnings;

If the Perl script is use warnings; (which almost always worth doing), then use a string in numeric context will print on STDERR warning:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my $str = 'Hello';

print $str + 100;

Here is the program output:

Argument "Hello" isn't numeric in addition (+) at script.pl line 8.
100

Recommendation

There is a recommendation not to use this feature of the language. If you need to get a number from the string, do it explicitly with the help of regular expressions. So you can just describe the format in which you expect to receive the data and will be able to catch the situation when the data arrives in the wrong format (instead of silent receipt of zero).

Here is a sample code. We know about the data at the beginning of the string is an integer and we need to calculate the sum of all numbers in all rows.

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my @strings = (
    '10 apples',
    '0 potatoes',
    '8 oranges',
    'nine lemons',
);

my $sum = 0;

foreach my $str (@strings) {
    if ($str =~ /^([0-9]+)/) {
        $sum += $1;
    } else {
        die "String '$str' is in incorrect format";
    }
}

print $sum;

When you run this program we get the error String 'nine lemons' is in incorrect format at script.pl line 19.. Thanks we see that in the data there is a problem. Depending on how we can either correct the data instead of a string 'nine lemons' use the string '9 lemons', or you can explicitly ignore this line in a loop next if $str eq 'nine lemons'.

If we had used the standard way that Perl convert string to a number, the loop would be much simpler:

foreach my $str (@strings) {
    $sum += $str;
}

But in this case, we would not know that data does not match the format we expect.

Other articles

Comments