みかづきメモ

プログラミング学習帳 ♪(✿╹ヮ╹)ノ

Perl の false を追いかける

Perl 触ってて例えば、下のようなコードがあって、 $r には何が入っているのかという問題。

sub is_even {
  $_[0] % 2 == 0;
}

my $r = is_even(1); # false

print $r としても何も表示されないので ''だと思っていたのだけれども、違っていた。
例えば以下のコードはすべて true として評価されるし、警告も出ない。

use feature qw/say/;
use strict;
use warnings;

my $r = 1 > 5; # false

if ($r eq '') {
  say 'empty string';
}

if ($r == 0) {
  say 'zero';
}

# こっちは警告だされる
# my $empty = '';
# say 'true 0' if $empty == 0;

調べてみると、 $r に入っている値は '' でもあるし、 0 でもある 特殊な値とのこと。
(Special False Value だとか、 Special Perl False Value だとか言われているみたい)。
文字列が欲しい場所では '' が返ってくるし、数値が欲しい場合は 0 がやってくる。 で、文字列と比較されようが、数値と比較されようが、警告が出ることもない。

どんな状態で Perl で保持されているかは、 XS 向けのデバッグライブラリで確認できる。

use Devel::Peek;

my $number  = 0;
my $double  = 0.0;
my $string  = '';
my $boolean = !!0;

# SV = Integer, NV = Double, PV = String
Dump(\$number);  # SV = 0
Dump(\$double);  # NV = 0
Dump(\$string);  # PV = ""\0
Dump(\$boolean); # SV = 0, NV = 0, PV = ""\0

ちなみに、この値が欲しければ !1 なり !!0 なりすれば得られる。

参考 :