118

別の Stack Overflow の質問 で、Leon Timmermansは次のように主張しました。

プロトタイプを使用しないことをお勧めします。それらには用途がありますが、ほとんどの場合ではなく、これには間違いありません。

なぜこれが真実なのですか(またはそうでないのですか)?私はほとんどの場合、自分の Perl 関数のプロトタイプを提供していますが、他の人がそれらの使用について悪いことを言っているのを見たことがありません。

4

4 に答える 4

123

正しく使用すれば、プロトタイプは悪くありません。問題は、Perl のプロトタイプが人々の期待どおりに機能しないことです。他のプログラミング言語のバックグラウンドを持つ人々は、関数呼び出しが正しいこと、つまり、正しい数と型の引数を持っていることを確認するためのメカニズムをプロトタイプが提供することを期待する傾向があります。Perl のプロトタイプは、このタスクにはあまり適していません。悪いのは誤用です。Perl のプロトタイプには、特異で非常に異なる目的があります。

プロトタイプを使用すると、組み込み関数のように動作する関数を定義できます。

  • 括弧はオプションです。
  • コンテキストは引数に課せられます。

たとえば、次のような関数を定義できます。

sub mypush(\@@) { ... }

そしてそれを次のように呼び出します

mypush @array, 1, 2, 3;

\配列への参照を取るためにを記述する必要はありません。

簡単に言えば、プロトタイプを使用すると、独自のシンタックス シュガーを作成できます。たとえば、Moose フレームワークはそれらを使用して、より一般的な OO 構文をエミュレートします。

これは非常に便利ですが、プロトタイプは非常に限られています。

  • それらはコンパイル時に見える必要があります。
  • それらはバイパスできます。
  • コンテキストを引数に伝播すると、予期しない動作が発生する可能性があります。
  • 厳密に規定された形式以外を使用して関数を呼び出すことが難しくなる可能性があります。

詳細については、perlsub のプロトタイプを参照してください。

于 2008-11-17T22:54:09.940 に答える
70

問題は、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 にのみ適用されます。

于 2008-11-17T21:55:27.937 に答える
30

上記の2つのポスターに同意します。一般に、使用$は避けるべきです。&プロトタイプは、ブロック引数 ( )、グロブ ( *)、または参照プロトタイプ ( \@\$\%\*)を使用する場合にのみ役立ちます。

于 2008-11-18T17:26:45.980 に答える