これでも正解ではありますが、perlの場合もっと簡単な方法があります。
各言語間の参照と値渡し - @author pyridoxin
sub swap {
my ($x , $y) = @_;
$$temp = $$y;
$$y = $$x;
$$x = $$temp
}
[codepad]
sub swap {
my $tmp = $_[0];
$_[0] = $_[1];
$_[1] = $tmp;
}
my ($a, $b) = (1, 2);
print "\$a = $a, \$b = $b\n";
swap($a, $b);
print "\$a = $a, \$b = $b\n";
これは、Referenceが存在しなかったPerl 4以前からの仕様です。
もちろん、
sub swap($$){
($_[1], $_[0]) = ($_[0], $_[1]);
}
としてもうまく行きます。
Perl 5以降では、subの書き方として
sub meth{
my $self = shift; # shift @_ の略
# ....
}
とか
sub func{
my ($a, $b, $c) = @_;
# ....
}
とかという具合に、最初にレキシカル変数に@_の内容をコピーするのが一般的ですが、これは不用意に参照元を書き換えないための工夫とも言えます。
なお、foreachやmapなどにおける$_も参照です。
my @a = (0..10);
print join(', ', @a), "\n";
$_ *= 2 for @a;
print join(', ', @a), "\n";
map { $_ + } @a;
print join(', ', @a), "\n";
これまたPerl 5では、
for my $item (@array){
# ....
}
という書き方がサポートされ、不用意に参照元を書き換える可能性を低くしています。
これ、知ったときには結構ギョっとしたのですが、おかげで末尾参照を手で最適化したりも出来ます。
404 Blog Not Found:perl - to goto or not to goto, that's the continuation
sub _fib_g{
my ($n, $f1, $f2) = @_;
return $f2 if $n == 0;
# _fib_g($n - 1, $f2, $f1 + $f2)
@_ = ($n - 1, $f2, $f1 + $f2);
goto &_fib_g;
}
sub fib_g{ _fib_g(shift, 0, 1) };
ナントカと駱駝は使いよう....
Dan the Refer(ent|rer)
>
>for my $item (@array){
> # ....
>}
>という書き方がサポートされ、不用意に参照元を書き換える可能性を低くしています。
この書き方って、
変数に my がついていても、@arrayの要素を書き換えますよね。Perlの罠ですよね。LarryWallのPerl本にも書いてあった。