I get an error like 'Argument "6.21_03" isn't numeric'


In bug 3811 the following error was reported while SpamAssassin is built:

Argument "6.21_03" isn't numeric in subroutine entry at Makefile.PL line 8.
Argument "6.21_03" isn't numeric in numeric ge (>=) at Makefile.PL line 139.
What email address or URL should be used in the suspected-spam report
text for users who want more information on your filter installation?
(In particular, ISPs should change this to a local Postmaster contact)
default text: [the administrator of that system] 

information required)? (y/n) [n] 

Checking if your kit is complete...
Looks good
Writing Makefile for Mail::SpamAssassin
Makefile written by ExtUtils::MakeMaker 6.21_03

Somebody else reported a similar error (in combination with Net::DNS) when spamd starts up:

Sep 29 21:36:53 bizio spamd[17905]: Argument "0.47_01" isn't numeric in numeric lt (<) at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Dns.pm line 1229.

In those cases these are actually warnings and no errors and are caused by some bug in Perl (reproduced with 5.8.4 and 5.8.5). Underscores in numbers are completely fine in Perl and normally just ignored. So any complains by Perl that a value which only consists of digits, a periods and underscores isn't numeric can be simply ignored.

Technical background

In Perl underscores in numbers are used to make numbers easier to read, especially in version numbers the part after the underscore is often used as a revision or build number.

The problem is that any numbers with underscores once they are "stringified", won't be recognized as numbers anymore; Perl will then issue a warning if those are enabled. This is reproducable with the following commands:

$ perl -wle 'print(( "1_000" > 0 )*1)'
Argument "1_000" isn't numeric in numeric gt (>) at -e line 1.
$ perl -wle 'print(( "1_000" == 1000 )*1)'
Argument "1_000" isn't numeric in numeric eq (==) at -e line 1.
$ perl -wle 'print(( "1_000" == 1 )*1)'
Argument "1_000" isn't numeric in numeric eq (==) at -e line 1.

As the last both commands show will Perl just ignore everything after the underscore, which can lead to unexpected results when comparing numbers. That's the bad news.

In the SpamAssassin codebase there aren't anywhere numbers used which contain an underscore – the warnings are produced by the $VERSION variable of external modules. And there's no place where the code checks for such an exact version that the ignored part of the fractions would have any impact. That's the good news.