Perlの関数引数は参照渡し
- 作者: Randal L. Schwartz,brian d foy,Tom Phoenix,吉川英興,伊藤直也,田中慎司,株式会社ロングテール/長尾高弘
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2006/10/21
- メディア: 大型本
- 購入: 9人 クリック: 389回
- この商品を含むブログ (99件) を見る
Perlにおける関数引数は基本的に「参照渡し」だという事がちゃんと分かっていなかったというか、「続・初めてのPerl」の「リファレンス入門」を読んでいるうちに混同してしまっています。
#!/usr/bin/perl use strict; use warnings; my @array = ( "hoge", "foo", "var" ); my $ref = \@array; foreach my $tmp (@array){ print "before : ", $tmp, "\n"; } &like_pass_by_value($array[0]); &edit_function_arg($array[1]); &edit_array(@array); &edit_array_element(@array); &edit_array_reference($ref); foreach my $tmp (@array){ print "after : ", $tmp, "\n"; } # 関数の中で引数をレキシカル変数に代入して使うと、まるで値渡しのようにみえる sub like_pass_by_value { my $tmp = shift; $tmp = $tmp."test"; } # しかし、実際は参照渡しなので、関数引数を直接いじると元の実体を更新することになる sub edit_function_arg { $_[0] = $_[0]."_changed"; } # ただし、配列を引数として渡した場合、@_は参照渡しではなく値渡し sub edit_array { push @_, "array_add"; } # しかし、要素単位で見ると参照渡し?? sub edit_array_element { $_[2] = "element"; } # 配列を引数で渡すときは配列の参照を渡すと参照渡しになる sub edit_array_reference { my $ref = shift; push @{$ref}, "ref_add"; }
上記のスクリプトの実行結果は以下のようになります。
[user@colinux 20070925]$ ./reference_test.pl before : hoge before : foo before : var after : hoge after : foo_changed after : element after : ref_add [user@colinux 20070925]$
とりあえず大前提として、Perlの関数引数は「参照渡し」が基本で、関数内部でレキシカル変数に代入するとまるで「値渡し」のように思えるだけ、というのはよく理解できたのですが。
関数引数に配列を渡す場合がまだクリアになりません。上記の試しのように動きとしては「配列全体」として扱う場合には、「値渡しのように」というか、サブルーチン内のローカルなスコープのものをいじっているように見えますが、その配列の要素を一個取り出して更新するとそれは外にある実体に影響しています。
配列そのものを渡した場合、その配列自体は「値渡し」だが、その要素単位で取得した場合(変数の場合同様に)「参照渡し」になるということでしょうか。
#ちゃんと理解したらまた書く