Perl日記

PerlとかRubyとかPHPとかPythonとか

looks_like_number()

昨日、looks_like_number()を使ったつながりで、実装はどんな風なんだろうと思ってperldoc -mしてみた。

/path/Scalar/Util/PP.pm
sub looks_like_number {
  # (略)
  return 1 if (/^[+-]?[0-9]+$/); # is a +/- integer
  return 1 if (/^([+-]?)(?=[0-9]|\.[0-9])[0-9]*(\.[0-9]*)?([Ee]([+-]?[0-9]+))?$/); # a C float
  return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i) or ($] >= 5.006001 and /^Inf$/i);

  0;
}

実際の判定は三つの正規表現
一個目はよく分かる。

/^[+-]?[0-9]+$/

初めに正負の記号があるかないか、次の文字目以降が数字の連続かどうか。
二個目もまだ分かる。

/^([+-]?)(?=[0-9]|\.[0-9])[0-9]*(\.[0-9]*)?([Ee]([+-]?[0-9]+))?$/

コメントのままのC言語float型。1.513819e+38みたいな。
こんなんも数値としてみてくれるのか…。
三個目は。

   ($] >= 5.008    and /^(Inf(inity)?|NaN)$/i)
or ($] >= 5.006001 and /^Inf$/i              )

Perlのバージョンが5.8以上なら文字列「Inf」「Infinity」「NaN」が、
Perlのバージョンが5.6.1以上5.8未満なら文字列「Inf」が、ケースインセンシティブで数値と見なされる。


僕としては「無限」とか「数値ではない」とか滅茶苦茶数値っぽくないような感じなんだけど…。
計算結果としての「NaN」だから数値、みたいな?
まあ実際のところ、何をもって『数値』とするかにも拠るか。


ただ気になったところ。

use Scalar::Util qw/ looks_like_number /;
print looks_like_number(123), "\n";
4352

うえー。なんでやねん。
他、調べたらこんな感じだった。

print looks_like_number(0),     "\n"; #=> 4352
print looks_like_number(-120),  "\n"; #=> 4352
print looks_like_number(1.2),   "\n"; #=> 8704
print looks_like_number('1.513819e+38'), "\n"; #=> 4
print looks_like_number('Inf'), "\n"; #=>   20
print looks_like_number(undef), "\n"; #=>    0
print looks_like_number('ok'),  "\n"; #=>    0

boolean的にはあってるけど、return 1 か 0 じゃないの?


参考:
The CPAN Search Site - search.cpan.orgperlapi - perldoc.perl.org404 Blog Not Found:perl - $scalarの中身が数値か否かを判定するlooks_like_number(Scalar::Util) - 数値であるかどうかの判定を行う - サンプルコードによるPerl入門