Perlにおけるdefined演算子は、値が定義されているかどうか(undefでないか)を確認します。以下のことを区別することが重要です:
defined($x)は、$xがundefでない場合にtrueを返します(値が何であれ、空の文字列や0であっても関係ありません)。defined($hash{$key})は、要素の値が定義されているかどうかを確認しますが、キー自体が存在することは保証しません。defined($array[$i])も同様に、要素が定義されている場合がありますが、配列の長さは異なる場合があります。existsを使用します。例:
my %h = (a => undef); if (exists $h{a}) { print "Key 'a' exists "; } if (defined $h{a}) { print "Key 'a' is defined "; } else { print "Key 'a' not defined "; }
結果:
Key 'a' exists
Key 'a' not defined
exists $hash{$key}とdefined $hash{$key}の違いは何ですか? いつハッシュのdefinedチェックが予期しない結果をもたらす可能性がありますか?
回答: defined $hash{$key}は値をチェックしますが、キーが存在しない場合は未定義の値が返されます。キーが存在するがその値がundefの場合、definedはfalseを返します。しかし、キーが存在しない場合もfalseです。したがって、キーの存在を確認するには、常にexistsを使用してください。
例:
my %h = (foo => undef); if (defined $h{foo}) { ... } # false if (exists $h{foo}) { ... } # true
物語
あるプロジェクトでは、「準備完了」フラグを
defined($status{$id})としてチェックしており、値がundefの場合はそのタスクは未処理と見なされました。しかし、undefのキーは有効であり、existsチェックがなく、その結果として処理済みデータの一部が再処理されました。
物語
データをファイルからインポートしていたプログラマーが、文字列を
if (defined $line && $line ne '')として比較していました。問題: 時々、$lineはゼロの文字列'0'になる可能性がありました。そのような文字列は空ではありませんが、definedとの比較は(ne ''の代わりに)これらの文字列を失うことにつながりました。
物語
大きなPerlスクリプトがハッシュを扱っていて、唯一の要素存在チェックがdefinedだったため、undefの値を持つキーにバグが発生し、報告書のデータが失われてしまいました。