メメメモモ

プログラミング、筋トレ、ゲーム、etc

perlのコンテキストについて

perlを書いているときは「コンテキスト」のことについて、ずっと意識している必要がある。
コンテキストを理解していれば、

などが、なんとなく判別できるようになる。



コンテキストは、以下の二種類がある。

  • スカラーコンテキスト
  • リストコンテキスト

スカラーコンテキストとは以下のようなものが書かれているところ。

1         # 数値
'hoge'    # 文字列
$hoge     # スカラー変数
\@hoge    # リファレンス

リストコンテキストとは以下のようなものが書かれているところ。

@array    # 配列
%hash     # ハッシュ
(1, 2)    # リスト

perlプログラムを書いているときは、どちらのコンテキストになっているのかを意識するようにする。


代入

代入では、左辺と右辺がそれぞれどのコンテキストになっているのかを意識する。
ほとんどの場合は、同じコンテキストになるようにする。


左辺も右辺もスカラーコンテキストの場合。

# 左辺がスカラー、右辺もスカラー
my $a = 'test';
my $b = $a;



左辺も右辺もリストコンテキストの場合。

# 左辺がリスト、右辺もリスト
my @a = (1, 2, 3);
my @b = @a;
my ($a, $b) = (1, 2);
my ($a, $b) = @list;

my %a = (a => 1, b => 2);
my %b = %a;



配列とハッシュは共にリストコンテキストになるので、相互代入することができる。
perlのハッシュで使われている「=>」は、「,(コンマ)」と等価になる。

my @a = (a => 1, b => 2);  # -> ('a', 1, 'b', 2)
my %b = @a                 # -> (a => 1, b => 2)

my %a = ('a', 1, 'b', 2);  # -> (a => 1, b => 2) ※順番は保持されない




リファレンスはスカラー値なので、スカラー変数で受け取る。

# 配列リファレンス
my $array_ref = \@a;

# ハッシュリファレンス
my $hash_ref = \%a;

# 無名配列リファレンス
my $array_ref = [1, 2, 3, 4];

# 無名ハッシュリファレンス
my $hash_ref = { a => 1, b => 2 };





配列リファレンスをデリファレンスすると、リストコンテキストになるので、配列変数で受け取る。
ハッシュのリファレンスも同じ感じ。

# デリファレンス後はリストコンテキストなので、配列変数で受け取る
my @a = @{ $array_ref };
my %a = %{ $hash_ref };





for文


for文のカッコの中はリストコンテキストになるので、リストを渡すようにする。

for my $a ( 1, 2, 3 ) {}

for my $a ( @array ) {}

for my $a ( @{ $array_ref } ) {}


関数


関数の引数は、無名配列「@_」で受け取られる。
左辺がリストコンテキストである場合の代入だと考えると良い。

func($a, $b);

sub func {
    my ($a, $b) = @_;
}




配列リファレンスを引数にする場合。

func($a, \@list);

sub func {
    my ($a, $list_ref) = @_;

    my @list = @{ $list_ref };
}



関数の返り値を受け取る場合も、返り値のコンテキストを意識する。

# 文字列を返す
sub func1 {
    return 'a';
}
my $result = $func1();


# 配列を返す
sub func2 {
    my @list = (1, 2, 3);
    return @list;
}
my @result = func2();
my ($a, $b, $c) = func2();


# 配列リファレンスを返す
sub func3 {
    my @list = (1, 2, 3);
    return \@list;
}
my $result = func3();





その他参考ページ

この他にも色々なパターンや例外があるので、後は以下のようなページで参考にする。