配列を操作する演算子

オープンソースのソースを読んではみようみまねで書くだけだと「何となくおまじない扱い」みたいな事が増えそうな気がしたので、基礎的なことからちゃんと技術書を読んで体系づけて消化しておこうと思います。

pop演算子、push演算子

Perlでは配列をデータのスタックとして用いる場面が非常に多いです。

配列に対してインデクスを使う(添え字付けする)ということは、Perlの良さを活用していない事になります。もし添え字付けの代わりにpop、push、および類似の演算子を使うと、あなたのコードは、たくさんの添え字付けをする場合に比べて、たいてい速くなります。

(初めてのPerl 第3版 P.55)

push - 最後尾に要素を追加する
pop - 最後尾から要素を取り出す

以下は、popの無効コンテキストについて。

my @array = 5..9;

my $first = pop @array;  
# $a : 9
# @array : (5,6,7,8) 

my $second = pop @array; 
# $b : 8
# @array  : (5,6,7)

pop @array; 
# 取り出した値はどこにも格納されないので破棄される
# (=無効コンテキスト/void context)
# @array : (5,6)

my @array2 = ();
my $c = pop @array2;
# $c : undef
# @array2 : ()

shift演算子、unshift演算子

push/popとは逆の動作をするのがshift/unshiftです。

shift - 先頭の要素を取り出す
unshift - 先頭に要素を追加する

サブルーチンの頭ではよく引数をshiftしますが、引数配列(パラメータリスト:@_)の先頭から順に取り出して、サブルーチン内の一時変数に代入するということをやっています。なので、代入後は$_[0]には何も入っていません。

また、変数をundefにするためにunshift $var;とよく書きますが、存在しない配列に追加する事で元の$varをundefにするという応用ということになるかと思います。

#!/usr/bin/perl

use strict;
use warnings;

my $hoge = "hoge";

print "before hoge : ", $hoge, "\n";
my $res = &test($hoge);
print "after hoge  : ", $hoge, "\n";
print "return      : ", $res, "\n";

sub test {
  my $arg = shift;
  defined $_[0] ?
     print "sub \$_[0]   : ", $_[0]."\n" :
     print "sub \$_[0]   : undef\n";
  $arg = "hogehoge";
  $arg;
}
[user 20071006]$ ./test.pl 
before hoge : hoge
sub $_[0]   : undef
after hoge  : hoge
return      : hogehoge
[user 20071006]$