13

空でない場合(したがってブール値の意味で真)@a = @b || @cを取得することを目的として、割り当ての複雑なバリエーションを実行したいと思います。ドキュメントには、私にはできないことが明記されています。(そしてそれは事実についても正しいです!)@b@c

「||」、「//」、および「&&」演算子は、最後に評価された値を返します(0または1を返すCの「||」および「&&」とは異なります)。

[...]

特に、これは、割り当てのために2つのアグリゲートから選択するためにこれを使用してはならないことを意味します。

@a = @b || @c;              # this is wrong
@a = scalar(@b) || @c;      # really meant this
@a = @b ? @b : @c;          # this works fine, though

残念ながら、それは本当に私に理由を教えてくれません。

私が予想したことはこれでした:

  • @a =は配列の割り当てであり、右側にリストコンテキストを誘導します。
  • @b || @cは右側で、リストコンテキストで評価されます。
  • ||Cスタイルの論理和論理和です。左から右に評価し(必要な場合)、コンテキストを伝播します。
  • @bリストコンテキストで評価されます。true(つまり、空でない)の場合、それが返されます。
  • そうでない場合は、@cリストコンテキストでも評価され、返されます。

明らかに、私の最後から2番目のステートメントは間違っています。なんで?そして、さらに重要なことに、ドキュメントまたはソースのどの部分がこの動作を説明していますか?

PS:質問の範囲外ですが、三項演算子を使用するというドキュメントの提案を控える理由は、私@bが実際には一時的なもの(関数呼び出しの結果)であるためです。

4

4 に答える 4

7

perlopでは、引用するセクションの数段落前に次のように記述します。

バイナリ"||" 短絡論理OR演算を実行します。あれは、
左のオペランドが真の場合、右のオペランドも評価されません。
スカラーまたはリストコンテキストは、右のオペランドの場合は右下に伝播します
評価されました。

これは、リストコンテキストが左側のオペランドに伝播しないことを明示的に示していませんが、perlopの先頭は次のように述べています。

ごくわずかな例外を除いて、これらはすべてスカラー値で動作します
配列値ではなく、のみ。

したがって、右のオペランドに伝播するリストコンテキストはルールの例外であり、左のオペランドのコンテキストに関するステートメントがないことは、一般的なルールが適用されることを意味すると想定できます。

于 2009-08-31T14:23:10.667 に答える
7

論理和演算子 ( " ||" ) は、左辺の引数をスカラー コンテキストで評価します。

これを行う理由は、引数が真かどうかを判断するためです。スカラー コンテキストの特殊なケースであるブール コンテキストは、それをスカラー コンテキストに強制します。


C-style-Logical-Or」よりperldoc perlop

バイナリ " ||" は短絡論理 OR 演算を実行します。つまり、左のオペランドがtrue の場合、右のオペランドは評価されません。...


「スカラー値」から:perldoc perldata

.... Boolean コンテキストは、文字列や数値への変換が実行されない特別な種類のスカラーコンテキストです。

于 2009-08-31T14:21:06.630 に答える
2

なぜなら|| ?:のテスト引数と同様に、スカラーコンテキストで左側を評価します。三項を使用できない場合は、次の関数を使用してください。

sub or_array (\@\@) {
  return @{$_[0]} if ( scalar @{$_[0]} );
  return @{$_[1]};
}

@a = or_array(@b, @c);
于 2009-08-31T14:26:07.620 に答える
0

条件演算子を直接使用できない場合は、わずかに簡潔でない演算子を簡単に使用できます。

my $ref_b = [ @b ]; # Ideally, just return an arrayref from your function
my @a = @$ref_b ? @$ref_b : @c;

上記の回答によると、 の左側||が評価される論理コンテキストはスカラー コンテキストであり、@b実際には になりscalar(@b)、それが に割り当てられるため、コードは機能しません@a

于 2009-08-31T14:35:58.213 に答える