web-dev-qa-db-ja.com

Perl条件の「if」と「unless」の使用

Perlコードでifunlessを最適に使用するためのガイドラインは何ですか?状況によってどちらかを好む強い理由はありますか?

49
JSBձոգչ

Perlのベストプラクティスでは、アドバイスはunlessを使用しないことです。個人的に、私はそれが狂気だと思います。

そうでなければif( ! ... )と書く単純な条件があるときはいつでもunlessを使用します。 unlessバージョンは、特に接尾辞として使用する場合、より読みやすくなります。

do_something() unless $should_not_do_that;

unlessまたはelsifブロックがある場合など、事態がより複雑になる場合は、elseを避けることをお勧めします。 (幸いなことに、または恐らく残念なことに、あなたの視点に応じて、elsunlessはありません)

また、条件は常に、他のブール値で構成される複雑な式です。例えば、

unless( $foo and !$bar )

かなり紛らわしいですし、同等のifよりも利点はありません。

59
friedo

難解なケースは別として1 unlessは、if !。より明確で表現力豊かなコードを作成できるようにするために存在します。これは、この目標を達成するときに使用する必要があり、それを損なうときに避ける必要があります。

unlessは、ループ内のフロー制御に最も役立つことがわかりました。例えば.

while (<$fh>) {
    next unless /\S/;
    # ...
}

単純な否定については、否定されたifよりも明確であることがわかります。先頭の!コードを読み取るとき。

unless ($condition) {
    do_something();
}

if (!$condition) {
    do_something();
}

ただし、unless ... else、それはただ耳障りだからです。

後置形式では、コードの予想されるパスについてのヒントを提供します。

do_normal_thing() unless $some_unlikely_condition;

1)最後に評価される式は異なり、明示的なreturnなしでsubsの動作に影響を与える可能性があります。
35
Michael Carman

経験則では、「場合を除いて」はおそらくあまり使用されません。

これは、後置形式で特に役立ちます。例:

delete_old_widgets() unless $old_widget_count == 0

次の場合を除き、使用すべきではない状況:

  • 複合条件(および、または、ない)
  • else節あり
12
Grant McLean

私は最近、2つのネストされた「unless」節がどのように機能するかを誰かに説明しようとして1時間を費やしました。

あなたがそれを英語に変換しようとするなら、それはあなたを導くのに役立ちます。

正常に動作しない限り、シンプルです。例えば。

「あなたが静かでない限り、私はあなたを無視するつもりです」。

unless ($quiet) {
    ignore();
}

これは同じようにうまくいくと思いますが

「あなたが静かでない場合、私はあなたを無視するつもりです」

if (not $quiet) {
    ignore();
}

複雑になり始めるのは、否定があるときです。

「あなたがうるさくなければ、私はあなたを無視します」

unless ( ! $noisy) {
    ignore();
}

はるかに良く書かれた

「あなたがうるさいなら、私はあなたを無視するつもりです」

if ($noisy) {
    ignore();
}

したがって、否定もある場合は、「unless」を使用しないでください。

また、「ほかに」を使用しないでください

unless ($quiet) {
    ignore();
}
else {
    give_a_sweet();
}

「あなたが静かでない限り、私はあなたを無視します、さもなければ私はあなたに甘いものを与えます」

条件を反転して変更します。

if ($quiet) {
    give_a_sweet();
}
else {
    ignore();
}

「あなたが静かなら、私はあなたに甘いものをあげます、さもなければ私はあなたを無視します」。

複数の条件があると、面倒になります。

unless ($quiet and not $fidgit) {
    punish();
}

「あなたが静かであり、あなたがfidgitしない限り、私はあなたを罰します」。

(私の理解がここで失敗しているのでごめんなさい!)

再び、それを否定します。

if (not $quiet or $fidgit) {
    punish();
}

「あなたが静かでない、またはあなたがフィジットなら、私はあなたを罰します」。

最も単純な場合でも「unless」を使用する場合の問題は、しばしば(自分で、または、

それ以外の場合に使用すべき、または使用すべきでない場合が明確になることを願っていますか?

(別の意見がない限り?)

9
user3043717

私はこれらの種類の質問の動機を理解していますが、unlessのようなものの使用を具体的な経験則に要約することは本当に賢明ではないと思います。これは、Perlの多くの補助構文と同様に、プログラマーが自分の裁量で明確に表現できるように、プログラマーのマイナーな利便性として提供されています。私は、「Programming Perl」全体を通して、リード開発者によるものよりも多くの方法で言われているのを見てきました。高い目的や合理化はありません。私はこれが問題を解決することをよく知っていますが、私がそれを使用する際に課す唯一の制約は、コードをより明確にするというより広い目的に役立つことを確認することです。もしそうなら、すべては順調です。コードが理解可能かどうかを認識することはそれ自体直感的であり、ビルトイン修飾子/演算子/全体の構文のあらゆるニュアンス、および大規模なグループプロジェクトで制約とガイドラインが必要な場所に関する過度に一般化された使用条件の大きな一握りに減らすことはできませんこれを細かく分割しても意味がないと思います。

2
cikkle

私の意見ではない限り使用しないことです。私の理由は:

  • 構文によりコードが読みにくくなると思います。 ifを実行する単一の方法があると、物事がより簡単になり、一貫性が増します。
  • 後でelseステートメントを追加する必要がある場合は、ifを除いて本当に変更する必要があります。すでにifである場合は簡単です。
  • Exceptステートメント内のロジックがより複雑になると、「unless(x == 5 && y!= 7)」のような奇妙なコードになる可能性があります。これは、2番目のチェックで二重否定があるため奇妙です。
  • 物事を否定する他の方法があります、すなわちx!= 5
  • 他の言語とより一貫しています。他の言語にunless文があることは知りませんが、これには非常に良い理由があると思います。

Perlには、ifステートメント、if、unlessを作成してから、開始ではなく行の最後にチェックを入れる4つの方法があります。私は、他の言語にも一貫した単一の一貫した方法を大いに好みます。

ちょうど私の0.02ドルの価値。

1
MikeKulls

適切な...

Perlのベストプラクティスでは、次の場合を除いて使用しないことをお勧めします。個人的に、私はそれが狂気だと思います。

20年以上、その代替案(Perlがテンプレートを提供していなかった場合のほとんどは存在しなかった)よりもPerlを好んだ後、「狂った」評決に同意するだけでなく、「ベストプラクティス」を聞いて驚いています'それを取り除きたい。

とはいえ、一部のPerlプログラマーが「できるからという理由だけで」採用する暗黙的に難読化された代替案とは対照的に、明確にするために書かれたコードを強く好みます。 「unless」は「if」の明確な反対であり、したがって、「if」条件に否定を埋め込むための非常に便利な代替手段です。特に、条件に複数の演算子が含まれる場合。そして、その根拠は、else/elsifが後に続く場合でも適用されます。

1
edwin

個人的な意見かもしれませんが、if条件がaで始まる場合を除き、私は使用したいです!

0
David Brunelle

構文if(!$ condition)は、unless($ condition)と同等であり、同様に条件のNOT'ingを交換する場合も同様です。

個人的には、IFステートメントのみを使用することを好みます。どうして?覚えるのが少ないからです。 100行のコードがあり、その半分がif()を使用し、残りの半分がif()を使用している場合、if()ステートメントだけの場合よりもデバッグに多くの時間を費やす必要があります。

ただし、unlessとifのハングを「取得」することができます。そのため、2つの間の切り替えには時間がかかりません。しかし、それはif()対except()だけではありません。それを忘れないでください...

if($condition) {
    #passed-condition code
} else {
    #failed-condition code
}

...と同等です...

unless(!$condition) {
    #passed-condition code
} else {
    #failed-condition code
}

しかし、if(){...} elsif(){...}はどうでしょうか?どのようにそれをunless(){...} elsunless(){...}にしますか?ロジックが複雑になるほど、if()とwithout()の間を行き来することが難しくなります。記憶し、記憶のバランスをとる必要が少なくなればなるほど、自分のコードをより迅速にデバッグできるようになります。

0
HoldOffHunger