リファレンスを適当にまとめたもの
モジュールを作っているうちに、参照渡しと値渡しがわけがわからなくなってきたのでまとめておいてみる。
Perlは基本的に値渡しを行っている。
参照渡しをする場合は明示的にリファレンスを渡す必要がある。
渡された側でも、リファレンスを扱っているという認識で処理を行う必要がある。
■参照渡しをしない場合
my $v1 = 10;
my $v2 = 20;
my $result = &test($v1, $v2);
print $v1 . "\n";
print $v2 . "\n"
print $result . "\n";
sub test{
my ($val1, $val2) = @_;
$val1 *= 2;
return $val1 + $val2;
}
__END__
出力結果
10
20
40
■参照渡しをする場合
my $v1 = 10;
my $v2 = 20;
my $result = &test(\$v1, \$v2);
print $v1 . "\n";
print $v2 . "\n"
print $result . "\n";
sub test{
my ($val1, $val2) = @_;
$$val1 *= 2;
return $$val1 + $$val2;
}
__END__
出力結果
20
20
40
以上のように呼び出し先で、参照している値を弄ることができる。
ただし、以下のようにやると無意味。
■参照渡しの意味がない状態
my $v1 = 10;
my $v2 = 20;
my $result = &test(\$v1, \$v2);
print $v1 . "\n";
print $v2 . "\n"
print $result . "\n";
sub test{
my ($ref1, $ref2) = @_;
$val1 = $$ref1;
$val2 = $$ref2;
$val1 *= 2;
return $val1 + $val2;
}
__END__
出力結果
10
20
40
当たり前のことなのだが、呼び出したサブルーチンで、リファレンスをデリファレンスしているため、参照先の値は変わらない。
配列やハッシュの場合は以下のようになる。
my @arr = (10, 20, 30);
&test(\@arr);
foreach my $val (@arr){
print $_ . "\n";
}
sub test{
my ($arrRef)= @_;
my $i;
for($i = 0; $i < scalar(@$arrRef); $i++){
$$arrRef[$i] += 5;
}
}
__END__
出力結果
15
25
35
my %hash = {
'a' => 10,
'b' => 20,
'c' => 30
};
&test(\%hash);
while(my($key, $val) = each(%hash)){
print $key . ": " . $val . "\n";
}
sub test{
my ($hashRef) = @_;
my @hashKeys = keys %$hashRef;
my $i;
foreach my $key (@hashKeys){
$$hashRef{$key} += 7;
}
}
__END__
出力結果
17
27
37
その他メモ
配列のリファレンスの要素数
@arr = (10, 20, 30);
$arrRef = \@arr;
print $#$arrRef;
出力結果
2
よしこれで再帰関数作れる。
Perlは基本的に値渡しを行っている。
参照渡しをする場合は明示的にリファレンスを渡す必要がある。
渡された側でも、リファレンスを扱っているという認識で処理を行う必要がある。
■参照渡しをしない場合
my $v1 = 10;
my $v2 = 20;
my $result = &test($v1, $v2);
print $v1 . "\n";
print $v2 . "\n"
print $result . "\n";
sub test{
my ($val1, $val2) = @_;
$val1 *= 2;
return $val1 + $val2;
}
__END__
出力結果
10
20
40
■参照渡しをする場合
my $v1 = 10;
my $v2 = 20;
my $result = &test(\$v1, \$v2);
print $v1 . "\n";
print $v2 . "\n"
print $result . "\n";
sub test{
my ($val1, $val2) = @_;
$$val1 *= 2;
return $$val1 + $$val2;
}
__END__
出力結果
20
20
40
以上のように呼び出し先で、参照している値を弄ることができる。
ただし、以下のようにやると無意味。
■参照渡しの意味がない状態
my $v1 = 10;
my $v2 = 20;
my $result = &test(\$v1, \$v2);
print $v1 . "\n";
print $v2 . "\n"
print $result . "\n";
sub test{
my ($ref1, $ref2) = @_;
$val1 = $$ref1;
$val2 = $$ref2;
$val1 *= 2;
return $val1 + $val2;
}
__END__
出力結果
10
20
40
当たり前のことなのだが、呼び出したサブルーチンで、リファレンスをデリファレンスしているため、参照先の値は変わらない。
配列やハッシュの場合は以下のようになる。
my @arr = (10, 20, 30);
&test(\@arr);
foreach my $val (@arr){
print $_ . "\n";
}
sub test{
my ($arrRef)= @_;
my $i;
for($i = 0; $i < scalar(@$arrRef); $i++){
$$arrRef[$i] += 5;
}
}
__END__
出力結果
15
25
35
my %hash = {
'a' => 10,
'b' => 20,
'c' => 30
};
&test(\%hash);
while(my($key, $val) = each(%hash)){
print $key . ": " . $val . "\n";
}
sub test{
my ($hashRef) = @_;
my @hashKeys = keys %$hashRef;
my $i;
foreach my $key (@hashKeys){
$$hashRef{$key} += 7;
}
}
__END__
出力結果
17
27
37
その他メモ
配列のリファレンスの要素数
@arr = (10, 20, 30);
$arrRef = \@arr;
print $#$arrRef;
出力結果
2
よしこれで再帰関数作れる。
この記事のトラックバックURL:
何かしら