looks_like_number()の返り値とエクスクラメーションによるBoolean反転
昨日のlooks_like_number()の返り値がよくわからなかったので、cpanからinstallするときのtestを落として見てみた。
$ cpan cpan[1]> get Scalar::Util $ cd ~/.cpan/build/Scalar-List-Utils-1.23-npHgm2/t/ $ grep looks_like_number ./* ./lln.t:use Scalar::Util qw(looks_like_number); ./lln.t: ok(looks_like_number($num), "'$num'"); ./lln.t:is(!!looks_like_number("Inf"), $] >= 5.006001, 'Inf'); ./lln.t:is(!!looks_like_number("Infinity"), $] >= 5.008, 'Infinity'); ./lln.t:is(!!looks_like_number("NaN"), $] >= 5.008, 'NaN'); ./lln.t:is(!!looks_like_number("foo"), '', 'foo'); ./lln.t:is(!!looks_like_number(undef), '', 'undef'); ./lln.t:is(!!looks_like_number({}), '', 'HASH Ref'); ./lln.t:is(!!looks_like_number([]), '', 'ARRAY Ref'); ./lln.t:is(!!looks_like_number($bi), 1, 'Math::BigInt'); ./lln.t:is(!!looks_like_number("$bi"), 1, 'Stringified Math::BigInt'); ./lln.t:is(!!looks_like_number($foo{'abc'}), '', 'Tied'); ./lln.t:is(!!looks_like_number($foo{'123'}), 1, 'Tied'); ./lln.t:is(!!looks_like_number("\x{1815}"), '', 'MONGOLIAN DIGIT FIVE');
出た。
「!!」なんだこれは!!。
Perlにおけるエクスクラメーションマーク!って、Boolean反転っていうのは知ってたけど、えと、なんで二個連続で重ねてんの?
そういえば今までエクスクラメーションマーク!をifとかの条件分岐でした使ったことなかったから、何が返されてるのかは知らなかったっけ。
というわけで先に「エクスクラメーションマーク!」について調べる。
「!」一個
文字列の場合
say !'Hello';
何も出ない。
空文字列の場合
say !'';
1
1が出た。
数値[^0]の場合
say !198765; say !-1;
やっぱり何もでない。
数値[0]の場合
say !0;
1
1が出た。
undefの場合
say !undef;
1
1が出た。
リファンレスの場合
my $a_ref = []; say !$a_ref;
出ない。
出ないときの中身は空文字列かundefのどちらだろうか。
my $what = !1; say defined $what ? 'karamojiretsu' : 'undef';
karamojiretsu
空文字列でした。
ということは
あーなるほど。
だから上のテストはこうなっているのか。
is(!!looks_like_number($bi), 1, 'Math::BigInt');
一個目の「!」で空文字列になって、二個目の「!」で「1」になる、と。
つまりこれは前回のエントリ最後の、looks_like_number()は、1か0を返しているわけではないということを裏打ちしているわけだ。
1以上の正の値であることは保証しているけれど、それが何になるかは環境に依存するという感じかな(推測です)。
もう一つ。
is(!!looks_like_number(undef), '', 'undef');
一個目の「!」で「1」になって、二個目の「!」で空文字列になって、それがis()で比較されると。
でもなんでこれだとだめなんかな。
is(looks_like_number(undef), 0, 'undef');
こっちも何か保証されていないfalseが返ってくることがあるのだろうか。
参考:
[Perl][PHP]値がfalse ならtrue に、true ならfalse にするtoggle(ビット反転)はこう書ける | ブログが続かないわけ