重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

my @a = qw(a b c);

my @b = ( qw(e f g) );

これの違いは何なのでしょうか?
perlにおいて()で囲むのはリストとして扱うということなのでしょうが、いまいちよく分かりません。

教えてください

A 回答 (4件)

まず本題を先に済ませてしまうと


my @b = ( qw(e f g) );

my @b = qw(e f g);
の間に違いはありません. 全く同じことです. 「書き換えた後のコード」で
my @t =
( qw(a b c) );
となっているのは, 単に無名配列を作る
[ qw(a b c) ]
と形を合わせたかっただけではないでしょうか.

で余談:
#1 ではなんだかんだ書いたけど, でも「perlにおいて()で囲むのはリストとして扱うということ」と思っちゃうのはまあ無理ないと思います. だいたい
my @a = ("a", "b", "c");
って書くしね.

ただ, ここのかっこは実は「リスト」とは全く関係ありません. じゃあなんでかっこがあるかというと
優先順位を変えるため
です. Perl では代入演算子の方がコンマ演算子よりも優先順位が高いため
my @a = "a", "b", "c";
と書くと
(my @a = "a"), "b", "c";
と解釈されてしまうのですが, それでは困るので右辺にかっこをつけています. つまり
$a * ($b + $c)
のかっこと役割は全く同じです.

1 の
my $a = qw(a b c);

my $a = ("a", "b", "c");
と同じ意味で, この右辺は (コンマ演算子の動作により) 「"a", "b" の値は評価だけして捨て, "c" の値を返す」ということになります. なので $a の値は "c" となります.

上の
my @a = ("a", "b", "c");
では右辺がリストであるのに対し下の例ではリストになっていませんが, これは「代入演算子が左辺を見て右辺の評価の仕方を変えている」からです. つまり上の例では左辺が @a と配列になっているので「じゃあ右辺はリストとして計算しないとだめだな」としますし, 下の例なら左辺 $a がスカラー変数なので「右辺はスカラーとして計算しよう」となります. 専門的には, この「○○として計算しよう」というのを「コンテキスト」と呼びます. コンテキストにはいくつかの種類がありますが, とりあえずスカラーコンテキストとリストコンテキストの 2つをおさえておけばだいたい何とかなります.

2 の
my @a = qw(a b c);
my $a = @a;
ではまず配列 @a に値を代入します. 次にスカラー変数 $a に配列@a を代入していますが, この場合代入する変数 $a がスカラーなので右辺はスカラーコンテキストで評価されます. そして
スカラーコンテキストで配列を評価すると要素数が得られる
ため, @a の要素数である 3 が $a に入ります.

3 と 4 は同じ結果になりますが, ここでは代入の左辺 ($a) が「リストである」ことに注意が必要です. つまり「左辺はリスト」なので, 「右辺もリスト」として計算します. そして得られた値を「要素ごとに代入」しているので $a の値は "a" です. 「代入する変数」そのものはスカラーであっても, ($a) となっていればリストです.

なお, 無名配列を作る [] や無名ハッシュを作る {} は, その内部に対し (当然ですが) リストコンテキストで評価します.

さらに余談ですが, 「かっこをつけなくてもリストになる」例として「リストを要求する演算子」を挙げることができます. print はそのような演算子なので, たとえば
print $a, $b, "\n";
と書くと「$a, $b, "\n" からなるリスト」に対して print を適用する, という意味になります. もっとも, 現実的にはかっこをつけないといろいろ面倒なことがあったりしますが....
    • good
    • 0
この回答へのお礼

丁寧に解説していただき、本当にありがとうございました。おかげで、より深い理解につながったと思います。

お礼日時:2011/07/29 15:45

うっぷ, 不適切な例を出しちゃった.... 数字を入れると「なぜそうなるのか」が却ってわからなくなっちゃうのに....



#1, #2 の例は次のように変えてください:
1:
my $a = qw(a b c);

2:
my @a = qw(a b c);
my $a = @a;

3:
my ($a) = qw(a b c);

4:
my @a = qw(a b c);
my ($a) = @a;

この 4通りで最終的に $a にどのような値が入っているかを調べるといいかもしれない.
    • good
    • 0
この回答へのお礼

お返事ありがとうございます、お礼が遅れまして大変申し訳ございませんでした。

まだ、少し疑問が解消できていません。よろしければ、さらに回答していただけると助かります。浅学で申し訳ございません。

まず、ご指摘された 括弧 に「リストとして扱う」などという機能はありません.というところですが、私が持っている本には、リストリテラルに関して、値をコンマで区切って括弧で囲んだものとあります。そういう意味で括弧で囲むのはリストとして扱うということを書きました。表現の仕方というか、言葉足らずというか、私の不備でした。申し訳ございません。

回答にありましたものは以下のようになりました

1:
my $a = qw(a b c);
#c

2:
my @a = qw(a b c);
my $a = @a;
#3

3:
my ($a) = qw(a b c);
#a

4:
my @a = qw(a b c);
my ($a) = @a;
#a

まず
1:
my $a = qw(a b c);
#c

についてですが、これについてまずqwについて復習しました。
qwとはリストリテラルに関するショートカットでした
つまり
qw(a b c)
とは
("a", "b", "c")
と同じであるということなんだと思います。
a b c を順番にスカラー変数に格納するので最初の a b が消されて c が表示されているんだと思います。

次に
2:
my @a = qw(a b c);
my $a = @a;

ですが、まず配列にリストを格納しています。
そしてスカラー変数に配列の要素の個数を格納しているので
表示が3になりました。

次に
3:
my ($a) = qw(a b c);

ですが、さきほど書いたように、qw(a b c)は("a", "b", "c")なので、リスト値をスカラー変数に代入していることになります。
もしこれが、
my ($a, $b) = qw(a b c);
であれば、
$aと$bにそれぞれaとbが格納されます。
つまり、リスト代入なので、aのみが$aに格納されて、他の値は捨てられたと思います。

で最後の
4:
my @a = qw(a b c);
my ($a) = @a;

ですが、配列にリストを格納し、my ($a) = @a;がリスト代入の形なので$aにaが格納された。

以上を踏まえてもう一度最初の疑問について考えると

my @b = ( qw(e f g) );

とは

my @b = ( ("e", "f", "g") );

と同じということなので  特に意味は無い??

しかし、そもそもこの疑問は本に以下のように書かれていたので疑問に思ったのです

・・(省略)・・無名配列コンストラクタとは、他でもない角カッコのことです

my $ref =
[ qw(a b c) ];

この角カッコは・・(省略、無名配列を作成してリファレンスを返すと説明)・・このコードは以下のように書き換えられます。

my $ref
{
my @t =
( qw(a b c) );
$ref = \@t;
}

これは無名配列コンストラクタを分かりやすく説明するためにこうしたのでしょうか?

お礼日時:2011/07/29 10:04

そうそう, #1 に追加するけど


my ($a) = (1, 2, 3);
とか
my @a = (1, 2, 3);
my ($a) = @a;
とかも調べると面白いよ.
    • good
    • 0

代入する先の変数や代入する値が違う. 逆に言えば, 「指定した変数に指定したリストを代入する」という「意味」は全く同じ.



そもそも「perlにおいて()で囲むのはリストとして扱うということなのでしょうが」というのが間違い. () に「リストとして扱う」などという機能はありません. たとえば
my $a = (1, 2, 3);

my @a = (1, 2, 3);
my $a = @a;
のそれぞれで $a の値がどうなっているか調べてみてください.
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!