3
my $target_type = (defined($item->{target_type}) && $item->{target_type}) 
                ? $item->{target_type} 
                : "";

my $target_id   = (defined($item->{target_id}) && $item->{target_id})
                ? $item->{target_id} 
                : "";

なぜ開発者は&&ほぼ同じ条件で使用したのですか?

4

6 に答える 6

6

どうやら彼はベルトとサスペンダータイプです。 はfalseであるため、(defined($x) && $x)ほぼ同等です。(違いは、ifが定義されているPerlの特別なfalse値になることですが、この場合は違いはありません。)おそらく以前は別の条件(のような)があり、警告を回避するためにテストが必要でした。初期化されていない値。その後、誰かがその状態を削除し、今は不要になったものを削除しようとは思わなかった。$xundef$xundef(defined($x) && $x)$x > 0defineddefined

(defined($x) && $x)onon15が指摘しているように)使用するもう1つの理由は$x、定義されていない可能性のある将来のメンテナンスプログラマーに強調することです。個人的にはコメントを使用しますが、TIMTOWTDIです。

于 2012-09-14T06:30:55.313 に答える
2

&&の右側は単独で使用できますが、$item->{target_type}定義されていない可能性がある、人間の読者のためのセマンティックヒントとして何度もそのような使用を見てきました。

したがって、LHSを削除して同様の動作を維持できたとしても、メンテナは、値が定義されているかどうかのチェックが不要であると誤解しやすい可能性があります。(タイトなループでない限り、その余分な評価のコストはごくわずかであり、ループ内であっても、インタープリターの最適化によって削除される可能性があります)。

于 2012-09-14T06:37:52.680 に答える
2

非常に短い答え: 古い perl での「初期化されていない値の使用」警告を回避し、その場合にデフォルトで定義された値を割り当てるためです。v5.10 以降では、 defined-or 演算子を使用します。

 $scalar //= "";
于 2012-09-14T14:09:03.303 に答える
1

&&「論理短絡」演算子です。最初に、彼はの定義をテストしてい$item->{targ_type}ます。定義されている場合(つまり、の左側&&が真である場合)にのみ、彼は真の値が含まれているかどうかをテストし$item->{target_type}ます。両方の条件が真の場合、$target_type(およびそれ以降)または$target_idに保持されている値が割り当てられます。これらの条件の1つが偽の場合、空の文字列が割り当てられます。$item->{target_type}$item->{target_id}

更新:構成を思いついたプログラマーの心を読み込もうとする:おそらく、コードはこれにつながる方法で進化し、プログラマーはそれが不要であることを認識するのに十分な長さでそれについて考えていませんでした。おそらくプログラマーは、定義、真実、虚偽、およびPerlで「偽」である値のタイプの違いについて不安を感じています。

于 2012-09-14T06:29:38.900 に答える
1

あなたの質問に答えるには心を読む必要がありますが、確率順に並べ替えたいくつかの理由を以下に示します。

  1. 著者は Perl プログラマーではなかったので、 の真実性、 が に評価され、式の残りの部分が意味のundefないものになるという事実、またはその両方に不快感を覚えました。defined undef && undef""
  2. definedコードは、テストがうまく機能するために必要なものを削除したリビジョンを見てきましたdefined $x && $x ne ''definedテストはその編集の残骸であり、メンテナにとってマイナスの価値があります。
  3. undef著者は、要素が明示的にテストされている可能性があることを強調したかった. これを行うためのより良い方法があります。それは、将来の読者が意図が何であったかを推測させない方法です。たとえば、コメントのように。
  4. 定義されている場合、$item->{target_type}計算にコストがかかるオーバーロードされたブール変換を持つオブジェクトが含まれている可能性があり、自滅的なマイクロ最適化を見ています。このケースは非常にまれです。面白いけど。
于 2012-09-14T07:42:56.770 に答える
0

同じ状態ではありません。

まず、彼は明確さをテストします

defined($item->{target_type})

一部の操作は、未定義の値で操作する場合は意味がありません。

2番目の条件では、彼は真または偽の値をテストします

$item->{target_type}

ただし、undeffalse値と同様に、2番目のテストは両方のケースをカバーします。

場合によっては、たとえば参照の内容に対してテストする場合など、同様のパターンが必要になります。

my $ref1 = "true";
my $ref2 = \("true");

if (ref $ref1 eq 'SCALAR' and $$ref1) {
  # This does not get executed
}
if (ref $ref2 eq 'SCALAR' and $$ref2) {
  # This does get executed
}
于 2012-09-14T06:30:32.613 に答える