3

私は Perl でいくつかの作業を行っていますが、条件演算子を使用して奇妙な結果に出くわしました。

問題のコード:

($foo eq "blah") ? @x = @somearray : @y = ("another","array");

このコードをコンパイルしようとすると、エラー " Assignment to both a list and a scalar at XXX line YY, near ');'" が発生します。エラーの原因を突き止めようとして、Perl で配列を表現するいくつかの異なる方法を使用してこれを書きましたが、それらはすべて同じエラーで返されます。最初は、割り当てステートメントの明らかな間違いだと思っていましたが、好奇心を満たすために、ステートメントをより冗長な方法で書き直しました。

if($foo eq "blah") {
    @x = @somearray;
} else {
    @y = ("another","array");
}

そのバージョンのコードは完全に問題なくコンパイルされました。

条件演算子の動作と基本的な if-else ステートメントの動作との間に、ここで欠けている細かい違いはありますか? 私は常に、条件演算子は 2 番目のステートメントの省略形に過ぎないと理解していました。2 つの間に機能上の違いがない場合、なぜ Perl は最初のステートメントに反対し、2 番目のステートメントには反対しないのでしょうか?

4

5 に答える 5

15
$ perl -MO=Deparse -e'($foo eq "blah") ? @x = @somearray : @y = ("別の","配列");'
-e 行 1、");" の近くでのリストとスカラーの両方への代入
-e にはコンパイル エラーがありました。
$foo eq '何とか' ? (@x = @somearray) : @y = ('別', '配列');
$ perl -MO=Deparse -e'($foo eq "blah") ? @x = @somearray : (@y = ("別の","配列"));'
$foo eq '何とか' ? (@x = @somearray) : (@y = ('別', '配列'));
-e 構文 OK

括弧に注意してください:?:は よりも強く結合し=ます。

于 2009-11-12T20:39:25.440 に答える
9

Perl の条件演算子は、

$変数 = (式) ? 真の代入: 偽の代入;

あなたがやっていることはうまくいくように見え、基本的には if/else ステートメントと同じです。しかし、問題が発生するのに十分なだけ標準とは異なります。

于 2009-11-12T20:49:07.553 に答える
7

perlopのドキュメントには、代入演算子を括弧で囲む必要があることが明確に記載されています。

演算子の優先順位を理解していない場合、括弧を使用しないことは、あなた自身の背中の棒です。自分のために賢くなりすぎるのはやめましょう!

于 2009-11-12T20:41:21.080 に答える
6

これはあなたの質問とは多少直交していますが、指摘する必要があります.Perlの条件演算子は、最初の引数から2番目または3番目の引数にコンテキストを伝播するため、望ましくない結果が得られます:

$x = ($foo eq "blah") ? $somevalue : ("another","array");

条件が false の場合、$x代わりに 1 つの整数値2(3 番目の引数の要素数) が割り当てられます。

一方、純粋なスカラー代入を実行しようとしていた場合:

# this is wrong, for the same order-of-operations reasons as with arrays
($foo eq "blah") ? $x = $somevalue : $x = "another value";

これは、状況を解決する合理的な (そして最良の) 方法です。

$x = ($foo eq "blah") ? $somevalue : "another value";

同様に、元のコードを次のように最適化できます。

@x = ($foo eq "blah") ? @somearray : ("another","array");
于 2009-11-12T20:58:07.800 に答える
2

これは、優先順位の低い「and」および「or」演算子を使用するのに適した場所です。

$foo eq 'blah' and @x = @somearray or @y = ('another', 'array');

@x = @somearray が常に true であると確信している場合。または、それらをひっくり返すことができます。

于 2009-11-12T20:55:18.557 に答える