Perlでは、手動で0にundefを変換する優雅な方法は何ですか?

StackOverflow https://stackoverflow.com/questions/1351103

  •  20-09-2019
  •  | 
  •  

質問

私はこのフォームでフラグメントを持っています:

my $a = $some_href->{$code}{'A'}; # a number or undef
my $b = $some_href->{$code}{'B'}; # a number or undef
$a = 0 unless defined($a);
$b = 0 unless defined($b);
my $total = $a + $b;
以上の2つの変数が懸念しているので、

現実は、もっと厄介です。

私が本当に書きたいことはこれです:

my $total = $some_href->{$code}{'A'} + $some_href->{$code}{'B'};

とundefを正しく0と評価されるが、私はほとんどすべての実行でこれらの警告を取得しています:

Use of uninitialized value in addition (+) at Stats.pm line 192.

これらのメッセージが離れて行くようにする最良の方法は何でしょうか。

NB:私は厳格な使用 'とそれが関連だ場合は、「警告を使用して」

役に立ちましたか?

解決

それはあなたがstrictwarningsを使用していることを良いことです。警告の目的は、Perlは意図しない(したがって正しくない)である可能性が高いの行動を見ていると、警告を発することです。あなたが意図的にそれをやっているときは、ローカルに警告を無効にするには完全に罰金です。 undefは、数値コンテキストで0として扱われます。あなたは両方の未定義の値を有し、かつ、それらがゼロに評価持つ大丈夫なら、単に警告を無効にします:

my $total;
{
  no warnings 'uninitialized';
  $total = $some_href->{$code}{A} + $some_href->{$code}{B};
}

注:あなたがする必要がある唯一の警告を無効にして、最小の範囲で行うことができます。

あなたが警告を無効に嫌うなら、

、他のオプションがあります。 5.10のとして、あなたはデフォルト値を設定する//(定義されて-OR)演算子を使用することができます。その人の前に、多くの場合、||(論理OR)を使用しますが、それはfalseと評価値のために間違ったことを行うことができます。 Perlのの前の5.10のバージョンではデフォルト値に堅牢な方法は、彼らがdefinedしているかどうかを確認することです。

$x = $y // 42;             # 5.10+
$x = $y || 42;             # < 5.10 (fragile)
$x = defined $y ? $y : 42; # < 5.10 (robust)

他のヒント

あなたは第二のために、「初期化されていない」の警告をオフにすることができます:

my $a;
my $b = 1;
{
    no warnings 'uninitialized';
    my $c = $a+$b; # no warning
}
my $c = $a+$b; # warning

それともゼロに短絡することができます:

my $d = ($a||0)+$b; # no warning

しかし私には非常に良い見ていません。

あなたがそれらを追加していると、ちょうどundefsををフィルタリングます。

use List::Util 'sum';

my $total = sum (0, grep {defined} $some_href->{$code}{'A'}, $some_href->{$code}{'B'});

あるいは

use List::Util 'sum';

my $total = sum (0, grep {defined} map {$some_href->{$code}{$_}} 'A', 'B');
my $a = $some_href->{$code}{'A'} || 0;
my $b = $some_href->{$code}{'B'} || 0;
my $total = $a + $b;

この場合、それが原因であなたのフォールバック値のfalseの値に未定義の値と同じに扱うためにOKです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top