web-dev-qa-db-ja.com

なぜ「!!」 Perlでの不正な形式と見なされますか?

最近の就職の面接プロセス中に、いわゆる「秘密」_!!_ operator を使用するサンプルPerlコードを提出しました。後で、コードについて話し合うときに、インタビュアーの1人が、なぜ私がそれを使用することを選択したのかを尋ね、それが悪い形式であると考えられていることを示しました。彼はその理由について詳しく述べなかった。

私のチームと私はこの演算子を何年も使用してきましたが、「悪い形式」と見なされたことに気づかなかったのです。

「バングバング」演算子には、副作用やその他の予期しない動作がありますか?なぜそれが、あるいはそれによって、「悪い形」と見なされるのでしょうか。慣用的な代替手段はありますか?

以下は、私が_!!_を受け入れ可能または望ましいと考えたいくつかの例です。

  1. ブール値を追加する例である、コーディング演習の実際のコード:

    _while (my $line = <$F>) {
        # snip
        exists $counts{lines} and $counts{lines} += !! chomp $line;
    }
    _
  2. ハッシュ値としてブール値を使用する(明らかに単純化された例):

    _sub foo {
        my ($input) = @_;
        my %responses = ( '' => "False", 1 => "True" );
        return $responses{ !! $input };
    }
    _
  3. ビットごとの演算、またはpack()でのブール値の使用:

    _sub foo {
        my ( $a, $b, $c ) = @_;
        my $result = !!$a + (!! $b)<<1 + (!! $c)<<2;
        return $result;
    }
    _
  4. 特定の値のみが真実であると見なす、データベースなどの外部ライブラリ/プロセスで使用するために型キャストを行う必要があります。

    _my $sth = $dbh->prepare("INSERT INTO table (flag,value) VALUES (?,?)")
    $sth->execute("i_haz_cheeseburger", !! $cheeseburger_string)
    _
58
Flimzy

_!!_は、Perlの2つのあいまいなものを利用します。_!_が返す特定の値と、可能な値の1つは、dualvar(文字列と数値の両方を含むスカラー)です。これらの動作を合成するために_!!_を使用することは確かに簡潔です。その粘り強さは大きなプラスになる可能性がありますが、かなり大きなマイナスになることもあります。 「Perlの使用はこのプロジェクトで禁止されています」というプロジェクトを強制するような機能を使用しないでください。

その式の真の値の出現をカウントするための$count += !! (some_expression)の代替手段はたくさんあります。 1つは三項$count += (some_expression) ? 1 : 0です。それも少しあいまいです。あなたが望むことをするための素晴らしいコンパクトな方法があります、それはpost-ifを使うことです:

_$x++ if some_expression;
_

これはまさにあなたがしていることを示しています。

38
David Hammen

質問全体はやや主観的なものなので、これまでに投稿した他の回答とは異なる意見を述べたいと思います。二重否定の形式は一般的には考慮しませんが、より読みやすい代替手段がある場合は、それを避けようと思います。あなたの例について:

  1. $count++ if $conditionなどを使用します。

  2. ハッシュキーとしての真理値?それは単に悪です。少なくとも、コードを保守しなければならない人にとっては驚くべきことです。

  3. ここでは、!!の使用が正当化されています。

  4. ここでは三項演算子を使用します。 dualvarが渡されたときのexecuteの動作は本当に明確ではありません。

!!を使用してもまったく問題ないもう1つの状況は、特定の値をブール値にキャストするとき(たとえば、returnステートメント内)です。何かのようなもの:

# Returns true or false.
sub has_item {
    my $self = shift;
    return !!$self->{blessed_ref};
}

ほとんどのプログラマーは、boolへのキャストとしてよく使用される静的型付け言語の!!イディオムを知っている必要があります。それがやりたいことであり、不要な副作用の危険性がない場合は、二重否定を使用します。

19
nwellnhof

多分それはあなただけが見るコードにとってそれほど悪くはありません。

しかし、あなたの仲間の開発者は、ある日あなたのコードのバグを修正するのを見るかもしれません、そしてこれにつまずきます。 2つのオプションがあります

  1. 彼はあなたが間違いを犯したと考え、1つ削除します!、コードを無効にします
  2. これは単なるソフトウェアの腐敗だと彼は考え、両方を削除します!!再考せずに。他のコードをリファクタリングした後、突然ハングします...型の不一致?

いずれにせよ、彼らがそれに慣れていない限り、それは将来の開発者の時間を浪費します。理解できるコードは自分自身のためではありません(まあ、それは役立つかもしれません)。

7
Sanchises

仕事によっては、それは多くのビジネスおよび面接理由にとっても悪い形です...

  1. チームプロジェクト、または他の多くの開発者がそれに取り組むことができる他のコードに取り組むときは、難読化しないでください(または会社のポリシーに従ってください)。
  2. sanchisesが言ったことについて行くと、それはより多くの作業を引き起こし、コードの意図を明確に表示しません。
  3. それは単に不要であり、上で説明したように、結果が機能しないシナリオが少なくとも1つあるように思えます。それがバグです。
  4. 面接であいまいなコーディングの使用を示すことは、それを行うためのより簡単で明確な方法がある場合、面接では好意的には見えません。
  5. インタビューとは、あなたがチームプレーヤーであることを示す場所であり、他の誰にも理解されていない奇妙ながらくたを出すつもりはありません(もちろん、未解決の問題の答えである場合を除きます)

pSインタビュアーがなぜそれを「悪い形」だと思ったのかを尋ねるのは良い形だったでしょう。便利なインタビューのフォローアップのヒントは、彼にあなたに感謝を送り、彼がそれを「悪い形」と考える理由を彼に尋ねることです

3
jon