引数に複数の配列を指定
perlの場合,引数は配列@_
を使用してサブプログラムへ渡ります.したがって,サブプログラムf0
に3個のスカラ値を渡すプログラムは以下のようになります.
#!/usr/bin/perl -w
use strict;
sub f0{
my @arr=@_;
print "f0: @arr\n"; #print "f0: @_\n";でも同じ
}
f0(1,2,3);
3個のスカラ値を渡す上記プログラムは,3個のスカラ値からなる配列1個を渡す以下のプログラムと同じです.
#!/usr/bin/perl -w use strict; sub f0{ my @arr=@_; print "f0: @arr\n"; } my @arr=(1,2,3); f0(@arr);
複数の配列を引数として渡す場合,困ったことになります.つまり,こういうプログラムです.
#!/usr/bin/perl -w use strict; sub f0{ my (@arr1,@arr2)=@_; print "f0.arr1: @arr1\n"; print "f0.arr2: @arr2\n"; } my @a1=(1,2,3); my @a2=(4,5,6); f0(@a1,@a2);
実行結果はこうなります.
$ sam.pl f0.arr1: 1 2 3 4 5 6 f0.arr2:
サブプログラムf0
の引数として与えた二つの配列の全要素が,一つの配列@_
に入るため,サブプログラムf0
側では引数の切れ目がわからなくなるのです.その結果,f0
に最初に指定した@arr1
に全要素が入り,@arr2
には何も入らない結果となりました.
main: @arr1=(1,2,3) @arr2=(4,5,6) ↓ @_=(1,2,3,4,5,6) ↓ f0: @arr1=(1,2,3,4,5,6),@arr2=();
サブプログラムへ複数の配列を引数として渡す場合は,リファレンスを使います.
#!/usr/bin/perl -w use strict; sub f0{ my ($arr1,$arr2)=@_; リファレンスはスカラ型で受取る print "f0.arr1: @$arr1\n"; もらったリファレンスを配列として扱う print "f0.arr2: @$arr2\n"; } my @arr1=(1,2,3); my @arr2=(4,5,6); f0(\@arr1,\@arr2); 配列のリファレンスを渡す
実行結果はこうなります.
$ sam.pl f0.arr1: 1 2 3 f0.arr2: 4 5 6
リファレンスが指し示す内容をサブプログラム中で書き換えると,元の値も書き換わります.注意しましょう.
#!/usr/bin/perl -w use strict; sub f0{ my ($arr1,$arr2)=@_; print "f0.arr1: @$arr1\n"; print "f0.arr2: @$arr2\n"; $$arr1[0]='a'; #リファレンスの参照元を書き換える $$arr2[0]='b'; #リファレンスの参照元を書き換える } my @arr1=(1,2,3); my @arr2=(4,5,6); f0(\@arr1,\@arr2); print "main.arr1: @arr1\n"; #リファレンスの参照元が書き換わる print "main.arr2: @arr2\n"; #リファレンスの参照元が書き換わる
実行結果はこうなります.
$ sam.pl f0.arr1: 1 2 3 f0.arr2: 4 5 6 main.arr1: a 2 3 main.arr2: b 5 6
上記プログラムは,配列のリファレンスを返す[]
を使ってこのように書くこともできます.
#!/usr/bin/perl -w use strict; sub f0{ my ($arr1,$arr2)=@_; print "f0.arr1: @$arr1\n"; print "f0.arr2: @$arr2\n"; $$arr1[0]='a'; $$arr2[0]='b'; } my $arr1=[1,2,3]; #$arr1は配列(1,2,3)のリファレンス my @arr2=(4,5,6); #@arr2は配列(4,5,6) f0($arr1,\@arr2); #$arr1はリファレンスなので\は不要 print "main.arr1: @$arr1\n"; #$arr1を配列として扱う print "main.arr2: @arr2\n";