novaの日記: perl 覚書
配列を引数として渡す
関数に配列を引数として渡す場合は、引き渡す方も受け取る方も配列 (@) で OK です。
netra[~/src_perl/]> more ary01.pl
#!/usr/local/bin/perl5.9.5
my @ary_master = ("Rhapsody", "Sonata Arctica", "Royal Hunt");
output(@ary_master);
sub output{
my @ary_sub = @_;
foreach my $elem(@ary_sub){
print "$elem\n";
}
}
netra[~/src_perl/]> ./ary01.pl
Rhapsody
Sonata Arctica
Royal Hunt
しかし、渡したい引数が複数になると破綻します。
netra[~/src_perl/]> more ary02.pl
#!/usr/local/bin/perl5.9.5
my @ary_master = ("Rhapsody", "Sonata Arctica", "Royal Hunt");
my $tag_master = "*** ";
output($tag_master, @ary_master);
sub output{
my $tag_sub = @_[0];
my @ary_sub = @_[1];
foreach my $elem(@ary_sub){
print "$tag_sub$elem\n";
}
}
netra[~/src_perl/]> ./ary02.pl
*** Rhapsody
@ary_master の 0 番目の要素 (Rhapsody) しか渡りません。
ま、@_[2] にアクセスすれば @ary_master の 1 番目の要素 (Sonata Arctica) が得られるのですが、
面倒です。
この場合は @ary_master を参照渡し (\) します。
netra[~/src_perl/]> more ary03.pl
#!/usr/local/bin/perl5.9.5
my @ary_master = ("Rhapsody", "Sonata Arctica", "Royal Hunt");
my $tag_master = "*** ";
output($tag_master, \@ary_master);
sub output{
my $tag_sub = @_[0];
my $ary_sub = @_[1];
foreach my $elem(@$ary_sub){
print "$tag_sub$elem\n";
}
}
netra[~/src_perl/]> ./ary03.pl
*** Rhapsody
*** Sonata Arctica
*** Royal Hunt
参照渡しは実体では無く配列へのポインタ (みたいなモン?) を渡すので、受け取る側はスカラーです。
それを配列として使用する場合は前に @ を付けます。
尚、この参照渡しはネストが深まっても同様です。
netra[~/src_perl/]> more ary04.pl
#!/usr/local/bin/perl5.9.5
my @ary_master = ("Rhapsody", "Sonata Arctica", "Royal Hunt");
my $tag_master = "*** ";
output($tag_master, \@ary_master);
sub output{
my $tag_sub = @_[0];
my $ary_sub = @_[1];
output2($tag_sub, \@$ary_sub);
}
sub output2{
my $tag_sub2 = @_[0];
my $ary_sub2 = @_[1];
foreach my $elem(@$ary_sub2){
print "$tag_sub2$elem\n";
}
}
netra[~/src_perl/]> ./ary04.pl
*** Rhapsody
*** Sonata Arctica
*** Royal Hunt
また、参照渡しには、参照先を書き換えられるという利点も有ります。 C 言語でよくやる、「空配列を渡して、ソレに値を詰めさせることで複数の結果を一つの関数から get する」 処理も可能となります。参照先の配列に値を込めるには、デリファレンス (もう一個 $ を追加) して放り込みます。
netra[~/src_perl/]> more ary05.pl
#!/usr/local/bin/perl5.9.5
my @ary_master = ("Rhapsody", "Sonata Arctica", "Royal Hunt");
my $tag_master = "*** ";
output($tag_master, \@ary_master);
sub output{
my $tag_sub = @_[0];
my $ary_sub = @_[1];
edit(\@$ary_sub);
foreach my $elem(@$ary_sub){
print "$tag_sub$elem\n";
}
}
sub edit{
my $ary_sub2 = @_[0];
$$ary_sub2[1] = "Helloween";
}
netra[~/src_perl/]> ./ary05.pl
*** Rhapsody
*** Helloween
*** Royal Hunt
perl 覚書 More ログイン