別の Stack Overflow の質問 で、Leon Timmermansは次のように主張しました。
プロトタイプを使用しないことをお勧めします。それらには用途がありますが、ほとんどの場合ではなく、これには間違いありません。
なぜこれが真実なのですか(またはそうでないのですか)?私はほとんどの場合、自分の Perl 関数のプロトタイプを提供していますが、他の人がそれらの使用について悪いことを言っているのを見たことがありません。
別の Stack Overflow の質問 で、Leon Timmermansは次のように主張しました。
プロトタイプを使用しないことをお勧めします。それらには用途がありますが、ほとんどの場合ではなく、これには間違いありません。
なぜこれが真実なのですか(またはそうでないのですか)?私はほとんどの場合、自分の Perl 関数のプロトタイプを提供していますが、他の人がそれらの使用について悪いことを言っているのを見たことがありません。
正しく使用すれば、プロトタイプは悪くありません。問題は、Perl のプロトタイプが人々の期待どおりに機能しないことです。他のプログラミング言語のバックグラウンドを持つ人々は、関数呼び出しが正しいこと、つまり、正しい数と型の引数を持っていることを確認するためのメカニズムをプロトタイプが提供することを期待する傾向があります。Perl のプロトタイプは、このタスクにはあまり適していません。悪いのは誤用です。Perl のプロトタイプには、特異で非常に異なる目的があります。
プロトタイプを使用すると、組み込み関数のように動作する関数を定義できます。
たとえば、次のような関数を定義できます。
sub mypush(\@@) { ... }
そしてそれを次のように呼び出します
mypush @array, 1, 2, 3;
\
配列への参照を取るためにを記述する必要はありません。
簡単に言えば、プロトタイプを使用すると、独自のシンタックス シュガーを作成できます。たとえば、Moose フレームワークはそれらを使用して、より一般的な OO 構文をエミュレートします。
これは非常に便利ですが、プロトタイプは非常に限られています。
詳細については、perlsub のプロトタイプを参照してください。
問題は、Perl の関数プロトタイプが、人々が考えていることを実行しないことです。それらの目的は、Perl の組み込み関数のように解析される関数を作成できるようにすることです。
まず、メソッド呼び出しはプロトタイプを完全に無視します。OO プログラミングを行っている場合、メソッドがどのようなプロトタイプを持っているかは問題ではありません。(したがって、プロトタイプを作成する必要はありません。)
第二に、プロトタイプは厳密には適用されません。でサブルーチンを呼び出すと&function(...)
、プロトタイプは無視されます。したがって、それらは実際には型の安全性を提供しません。
第三に、彼らは遠く離れた不気味なアクションです. (特に、$
デフォルトのリストコンテキストではなく、対応するパラメーターがスカラーコンテキストで評価されるプロトタイプ。)
特に、配列からパラメーターを渡すのが難しくなります。例えば:
my @array = qw(a b c);
foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);
sub foo ($;$$) { print "@_\n" }
foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);
プリント:
a b c
a b
a b c
3
b
a b c
main::foo() called too early to check prototype
(警告が有効な場合)に関する3つの警告とともに。問題は、スカラー コンテキストで評価された配列 (または配列スライス) が配列の長さを返すことです。
組み込みのように機能する関数を作成する必要がある場合は、プロトタイプを使用してください。それ以外の場合は、プロトタイプを使用しないでください。
注: Perl 6 では、完全に改良された非常に便利なプロトタイプが作成されます。この回答は Perl 5 にのみ適用されます。
上記の2つのポスターに同意します。一般に、使用$
は避けるべきです。&
プロトタイプは、ブロック引数 ( )、グロブ ( *
)、または参照プロトタイプ ( \@
、\$
、\%
、\*
)を使用する場合にのみ役立ちます。