Perlでは、サブルーチンは特別な配列変数 @_ を通じて引数を受け取ります。ここには、渡されたすべてのパラメータが自動的に格納されます。Perlの特徴は、パラメータが @_ に参照で渡されるため、関数内で要素を変更すると、それが外部でも影響することです。
渡されたデータの予期しない変更を避けるために、引数は変数にコピーすることをお勧めします:
sub sum { my ($a, $b) = @_; return $a + $b; }
Perlの関数は常にリストの値を返し、関数の結果は最後に計算されたリストまたは明示的な return 文です。
sub minmax { my ($x, $y) = @_; return ($x < $y ? $x : $y, $x > $y ? $x : $y); } my ($min, $max) = minmax(4, 7); # $min = 4; $max = 7
スカラーコンテキストで関数を呼び出すと、返された要素の数が返され、結果をスカラーで囲まなければなりません。
Perlの関数に多くの変数を渡す方法は何ですか?元の変数の値を誤って変更しないために。
無意識に答える人はいます: "引数を普通に変数にコピーすればいい!"
正しい答え:
コピーはスカラーにのみ有効です。配列やハッシュを使う場合は、データの伝達を明示的に管理し、参照を使うべきです。
sub modify { my ($arr_ref) = @_; push @$arr_ref, 'new'; # 元の配列を変更 } my @data = (1, 2, 3); modify(\@data); # 現在 @data = (1, 2, 3, 'new')
歴史
歴史 1
大規模なレポート処理スクリプトの内部関数が、メインプログラムから渡された配列要素の値を変更していました。その結果、関数実行後に元のデータが歪められました。このエラーは、関数作者が入力値のコピーを作成せず、変更がローカルであると考えたためです。これは、配列の場合の @_ に対しては正しくありません。
歴史 2
Perl 4 からスクリプトを移行する際、チームは問題に直面しました: ネストされたハッシュを渡すことが関数呼び出し間でデータが「漏れ」させる結果をもたらしました。一つの関数でハッシュのフィールドを変更すると、他のコードの部分に影響を与えました。その原因は、リスト @ の中のハッシュへの参照でした。
歴史 3
開発者は結果の配列を返す関数を実装しましたが、呼び出す場所でスカラーコンテキストを使用しました:
$count = func(@params);。最初の返された要素が変数に代入されることが期待されましたが、実際には$countにはリスト内の要素の数が入っており、計算に遅延と混乱を引き起こしました。