Perl で配列要素やハッシュ要素にアクセスするときに $ が必要なのはなぜですか?
質問
Perl では配列とハッシュにはスカラーのみを含めることができるのに、配列またはハッシュ要素にアクセスするときに値がスカラーであることをインタプリタに伝えるために $ を使用する必要があるのはなぜですか?言い換えれば、配列があると仮定すると、 @myarray
そしてハッシュ %myhash
, 、なぜそうする必要があるのですか:
$x = $myarray[1];
$y = $myhash{'foo'};
ただ実行する代わりに:
$x = myarray[1];
$y = myhash{'foo'};
なぜ上記は曖昧なのでしょうか?
その場所に $ 以外のものがある場合、それは不正な Perl コードではないでしょうか?たとえば、次のすべては Perl では違法ではないでしょうか?
@var[0];
@var{'key'};
%var[0];
%var{'key'};
解決
スライスは違法ではありません。
@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};
そして、これが、ハッシュ/配列から単一の値を取得するかどうかを指定する必要がある理由の一部であると思います。
他のヒント
たった今使ったばかりです
my $x = myarray[1];
プログラム内で実行すると、驚いたことに、次のようなことが起こりました。
$ perl foo.pl
Flying Butt Monkeys!
それは、プログラム全体が次のようになっているためです。
$ cat foo.pl
#!/usr/bin/env perl
use strict;
use warnings;
sub myarray {
print "Flying Butt Monkeys!\n";
}
my $x = myarray[1];
したがって、myarray はサブルーチンを呼び出し、単一の要素 1 を含む匿名配列への参照を渡します。
これが、配列アクセスにシジルが必要なもう 1 つの理由です。
シジルはコンテナの戻り値の型を示します。それで何かが始まるとしたら @
, 、リストを返すことがわかります。で始まるなら $
, 、スカラーを返します。
ここで、シジルの後に識別子のみがある場合 (次のように) $foo
または @foo
, それなら、単純な変数アクセスです。続いて [
, 、その後に続く場合、それは配列へのアクセスです。 {
, 、ハッシュ上のアクセスです。
# variables
$foo
@foo
# accesses
$stuff{blubb} # accesses %stuff, returns a scalar
@stuff{@list} # accesses %stuff, returns an array
$stuff[blubb] # accesses @stuff, returns a scalar
# (and calls the blubb() function)
@stuff[blubb] # accesses @stuff, returns an array
人間の言語の中には、非常によく似た概念を持つものがあります。
しかし、多くのプログラマーはこれが混乱を招くと考えたので、Perl 6 では不変シジルを使用しています。
一般に、Perl 5 コンパイラはコンパイル時に、何かがリスト内にあるか、スカラー コンテキスト内にあるかを知りたいため、先頭のシジルがないと一部の用語があいまいになります。
これは有効な Perl です。 @var[0]
. 。これは長さ 1 の配列スライスです。 @var[0,1]
これは長さ 2 の配列スライスになります。
@var['key']
アレイは数値でのみインデックス化でき、他の2つだけで索引付けできるため、有効なPerlではありません(%var[0] and %var['key']
) は、ハッシュ スライスが {} を使用してハッシュのインデックスを作成するため、有効な Perl ではありません。
@var{'key'}
そして @var{0}
ただし、どちらも有効なハッシュ スライスです。長さ 1 のスライスを取得するのは明らかに普通ではありませんが、それは確かに有効です。
見る perldata perldoc のスライスセクションPerl でのスライスの詳細については、「Perl でのスライスの詳細」を参照してください。
スライスとコンテキストを使用できることはすでに指摘されていますが、シジルは変数であるものをその他すべてから分離するためにあります。適切な変数名を選択するために、すべてのキーワードやサブルーチン名を知っている必要はありません。これは、他の言語の Perl に関して私が見逃している大きな点の 1 つです。
一つ考えられる方法は、
$x = myarray[1];
は曖昧です - m という配列が必要な場合はどうすればよいでしょうか?
$x = m[1];
正規表現の一致とどうやって区別できるのでしょうか?
言い換えれば、構文は Perl インタプリタ、つまり解釈を支援するために存在します。
Perl 5 (Perl 6 で変更予定) では、シジルは コンテクスト あなたの表現の。
- ハッシュから特定のスカラーが必要なので、
$hash{key}
. - 配列から特定のスロットの値が必要なので、次のようになります。
$array[0]
.
ただし、zigdon が指摘したように、 スライス 合法です。彼らはそれらの式を次のように解釈します。 リスト コンテクスト。
- ハッシュに 1 つの値のリストが必要です
@hash{key}
作品 ただし、次のようなより大きなリストも同様に機能します。
@hash{qw<key1 key2 ... key_n>}
.配列からいくつかのスロットが必要です
@array[0,3,5..7,$n..$n+5]
作品@array[0]
サイズ1の一覧です。
「ハッシュコンテキスト」がないため、どちらも %hash{@keys}
または %hash{key}
意味がある。
それで、あなたは持っています "@"
+ "array[0]"
<=> < sigil = context > + < インデックス式 > を完全な式として使用します。
シジルはアクセスのコンテキストを提供します。
$
スカラーコンテキスト(スカラー変数またはハッシュの単一要素または配列の単一の要素)を意味します)@
リストコンテキスト(アレイ全体またはハッシュまたはアレイのスライス)を意味します)%
ハッシュ全体です
Perl 5 では、ベアワード識別子のデフォルトの解釈がサブルーチン呼び出しであるため、シジル ($ と @) が必要です (したがって、ほとんどの場合 & を使用する必要がなくなります)。