2012-02-16 8 views
12

スカラコンテキストでリストの割り当てが右側の要素の数を返す:リスト割り当て

scalar(my ($hello, $there, $world) = (7,8)); #evaluates to 2 

なぜそれが右側を評価し、2を生成する代わりに、新たに定義されたリストのん評価され、3を返す?私に

$helloは7を得るようにそれはそう、$thereそれは、リスト内の要素の数であるとして、3になると思われる、そのリストがスカラコンテキストで評価され、8を取得し、$worldundefを取得($hello $there $world )。そのコンテキストが評価された式の一部が返される影響私には奇妙なようだ:

my $greeting = (($hello, $there, $world) = (7,8)); #2 

my @greeting = (($hello, $there, $world) = (7,8)); 
my $greeting_length = @greeting; #3 
+1

実際には、左のリストがスカラーコンテキストで評価されたものだった場合、値は 'undef'になります。リストは配列ではありません。 – darch

+0

@ darch、それは意味をなさない。 '($ hello、$ there、$ world)=(7,8)'では、($ hello、$ there、$ world) '(および'(7,8) ')はスカラーコンテキストでは実行できません。リストの割り当ては、望むなら3を返しますが、理由はありません。 – ikegami

+0

私は「[list($ hello、$ there、$ world)]がスカラーコンテキストで評価される」というフレーズに正確に反応していました。 'my($ h、$ t、$ w)=(7、8、undef)を評価する。スカラー($ h、$ t、$ w) 'となり、リストは配列ではないことがわかります。 – darch

答えて

14

perlopの右(代入演算子のセクションの最後の文)上の要素をカウントするために文書化されています:

同様に、リストコンテキストのリスト割り当ては、割り当てられた左辺値のリストを生成し、スカラーコンテキストのリスト割り当ては、右辺の式によって生成された要素の数を返します。

あなたはこのようなものを書くことができるようにそれがあるようにそれが動作する理由:

while (my ($key, $value) = each %hash) { ... } 

それは代入の左辺の要素の数をカウントした場合、それは無限になりますループ。

これについて考えると、左側の要素の数は右側の要素の数と同じか、定数(スカラーのリストに割り当てるとき)です。最初のケースでは、どちら側でカウントしても違いはなく、2番目のケースでは、右手側のカウントがより便利です。

一方、リストコンテキストでは、代入演算子が左辺リストを返します。これは、これがより便利なためです。リストの要素を変更するコンテキストで使用する場合は、割り当てられたばかりの変数を変更する必要があります。

再:あなたの例では、あなたのコメントは、(7,8)はあなたがスカラーの長いリストに短いリストを割り当てると代入演算子は2を返す理由は2つの要素のリストであり、右側ではありません割り当てが行われる前に "padded out"をundefとしてください。代わりに、右側のリストから関連付けられた値を持たない変数は、デフォルト値にリセットされます。スカラー変数の場合は、undefです。配列の場合、それは空の配列です。ハッシュの場合、それは空のハッシュです。

+0

あなたの応答は理にかなっています。なぜこのように動作するのか理解していますが、どのように動作するのかもっと興味があります。 ikegamisの投稿に私のコメントを参照してください。 – Brian

+0

@Brianのリストコンテキストでは、左手のリストを取得しますが、スカラーコンテキストでは右手リストの数を取得します。どちらの場合でも、これは返すのが最も有益なものだからです。詳細については、私の更新答えを見てください。 – cjm

+0

@Brianでは、Perlには多くの関数と演算子があり、スカラーコンテキストではリストコンテキストで返す要素の数以外のものを返します。あなたは関数や演算子が返すものを見つけるためにドキュメントを読む必要があります。 – cjm

6
評価する側の文脈効果が評価されるのは私にとっては奇妙なようです:

それはありません。リスト代入演算子の両側(オペランド)が評価され、リスト割り当てがスカラーコンテキストまたはリストコンテキストで評価されるかどうかは、オペランドの評価にはまったく影響しません。

リスト割り当てがスカラーコンテキストで評価されるかリストコンテキストで評価されるかは、それが返す値にのみ影響します。

私は以前に2つの代入演算子とそれらがどのようにスカラーとリストコンテキストで振る舞うとの違いを明確にしようとMini-Tutorial: Scalar vs List Assignment Operatorを、作成しています。

+0

私はその文章を少し編集しました。「評価された式のどの部分に文脈が返ってくるかは私にとっては奇妙に思えます。「文脈は評価に影響せず、結果だけに影響することは知っていますが、使い方。代入の右辺が評価され、次に左辺に代入されると、スカラーはなぜ2になるのですか?右辺は3要素リストに評価され、スカラーに割り当てられます。それは、優先順位のルールを無視して、式のどの部分を返すかを選択することに決めたようなものです。 – Brian

+0

もちろん、 'my @greeting =(($ hello、$ there、$ world)=(7,8))'が '($ helloの代わりに' @ greeting' '(7,8) $ there、$ world) 'のようになりました。しかし、 '@ greeting'が'($ hello、$ there、$ world) 'を取得し、' $ greeting'が '(7,8)'の結果を得た場合、それは意味をなさないでしょう。 – Brian

+0

'$ greeting'は'(7,8) 'の結果を得ません。実際、 '$ greeting'が'(7,8) 'の結果を得ることは不可能です。これは'(7,8) 'がリストの値に評価され、リストの値をスカラーに割り当てることができないからです。 '@ greeting'と' $ greeting'の両方は、リスト割り当ての結果を取得します。これは、「LHSが評価した値のリスト」または「RHSが評価した要素の数」です。あなたは、他の結果をどのように役立てるかについて何らかの理由を与えずに、何かを戻す方が良いと示唆しているようです。 – ikegami