Perl の関数プロトタイプ

Perl 歴はもうかれこれ 5 年くらい.その間にも刻々と変化していってるのよね,Perl の仕様.といっても下位互換性が保たれてるから良いんだけど.

さて,Perl の文法は非常に柔軟というか,とにかくいろんな書き方がある.


sub func1
{
    return $_[0] + $_[1];
}
sub func2
{
    my ($arg1, $arg2) = @_;
    return $arg1 + $arg2;
}
sub func3
{
    my $arg1 = shift(@_);
    my $arg2 = shift;    # 1 行上と同じ意味
    return $arg1 + $arg2;
}
sub func4($$)
{
    my $arg1 = shift;
    my $arg2 = shift;
    return $arg1 + $arg2;
}
sub func5(\$\$)
{
    my $arg1 = shift;
    my $arg2 = shift;
    return $arg1 + $arg2;
}
# 以下 全て同じ結果 5 を得る
print &func1(2, 3);
print &func2(2, 3);
print &func3(2, 3);
print func3(2, 3);
print &func4(2, 3);
print func4(2, 3);
print &func5(2, 3);
#print func5(2, 3);  # syntax error.

どっかのサイトで 「仮引数の型と数を指定できる」 (例:func4) と知り,その後 (たぶん別のサイトで) 「型を指定するにはバックスラッシュを付記する (特に配列 '@' やハッシュ '%' を扱う場合)」 (例:func5) と知った.一方,呼び出しでは関数名の前に '&' を付記しなければならないと思っていた.以降 今まで func5 の形のプロトタイプを書き,&func5(2, 3); のように呼び出してた.しかし,そのようにプロトタイプを書いた場合と書かない場合の動作の違いが,これまでほとんど感じられなかった.「ただ分かりやすくするためだけなんかなぁ」 とさえ思っていた.

で,今日.func4 の形で書き,func4(2, 3); のように呼び出して初めて意味がある = 引数の型・数を構文チェックしてくれる ということを知った.…って FAQ にそのまんま書いてあるし orz (参考:perldoc.jp - perlfaq7 - What's the difference between calling a function as &foo and foo()?) あ~ぁ,片っ端から修正していかないと.でも今後は非常に助かること間違いなし.perl -cw マンセー.

因みに func4func5 の違いを検証してみた…んだけど,結局よく分からなかった.「何かが違う」 としか言えん.