ブログが続かないわけ

この日記のはてなブックマーク数
Webエンジニアが思うこと by junichiro on Facebook

0と空文字と未定義値の比較(Perl)

このエントリーを含むはてなブックマーク hateb
自戒のエントリー。
これを以て反省とかえさせてください。

タイトルの通り、こいつらをどう区別するかという話。
スカラー変数だと説明しづらいので、ハッシュで行く。
use strict;
use warnings;

my %data;
$data{'exists'} = 'OK!'; #1
$data{'zero'} = 0; #2
$data{'kara'} = ''; #3
# $data{'undef'} = ''; #4

my @keys = qw(exists zero kara undef);

%data に含まれる4つの値(正確には3つの値)を区別する。

■1. まずは全部表示しちゃう例。
foreach my $key ( @keys ) {
print "$key => $data{$key}¥n";
}

□1.結果
exists => OK!
zero => 0
kara =>
undef =>
ただし、use warnings がついているとundef のところで下記のwarningを吐きます。
Use of uninitialized value in concatenation (.) or string at ...

■2.次は、#1〜#3、つまり未定義値以外を全て表示する条件
foreach my $key ( @keys ) {
print "$key => $data{$key}¥n" if (defined $data{$key});
}

□2.結果
exists => OK!
zero => 0
kara =>
まあ、当然の結果なので特に説明なし。

■3.今度は空文字以外#1〜#2を表示する条件
foreach my $key ( @keys ) {
print "$key => $data{$key}¥n" if (defined $data{$key} && $data{$key} ne '');
}

□3.結果
exists => OK!
zero => 0
ここ重要! 0をしっかりと区別しなければならないことはたくさんあるよね。そのときは面倒でもこんな感じになる。defined ... の部分がない if($data{$key} ne '')だと、$data{$key} が未定義の場合にwarning を吐くので要注意。

■4.最後は、#1だけを表示したい例
foreach my $key ( @keys ) {
print "$key => $data{$key}¥n" if ($data{$key});
}
みんなが一番好きな書き方だね。
□4.結果
exists => OK!
実際には0は絶対に入ってこないという状況のもと3.と同じ用途で使われることもあるね。

だからこそ要注意。
0が絶対に入ってこないとき、または、0も条件外という時以外は4.の書き方はできないということ。


油断しているといまだにやってしまうので、自戒の念を込めて...
この記事のトラックバックURL
トラックバック機能は終了しました。
トラックバック
コメント









関連情報