私はしばらくの間Perlを使用してきましたが、今日私はこのコードに出くわしました:
sub function1($$)
{
//snip
}
これはPerlでどういう意味ですか?
私はしばらくの間Perlを使用してきましたが、今日私はこのコードに出くわしました:
sub function1($$)
{
//snip
}
これはPerlでどういう意味ですか?
これは、 2つのスカラー引数をとるプロトタイプを持つ関数です。
以下のコメントに記載されているように、一般的にPerlプロトタイプを実際に使用しないことには強い議論があります。最も強力な議論はおそらく次のとおりです。
2008年からのStackOverflowに関する議論があります:
MooseX :: Method::Signaturesモジュールに置き換えられる可能性があります。
他の答えが述べているように、$$
はプロトタイプを宣言します。他の答えが言っていないのは、プロトタイプが何のためにあるのかということです。これらは入力検証用ではなく、パーサーのヒントです。
次のように宣言された2つの関数があるとします。
sub foo($) { ... }
sub bar($$) { ... }
今、あなたが曖昧な何かを書くとき、例えば:
foo bar 1, 2
Perlはparensをどこに置くかを知っています。バーは2つの引数を取るので、それに最も近い2つを消費します。fooは1つの引数を取るので、barと2つの引数の結果を取ります。
foo(bar(1,2))
もう一つの例:
bar foo 2, 3
同じことが当てはまります。fooは1つの引数を取るので、2を取得します。barは2つの引数を取るのでfoo(2)
、3を取得します。
bar(foo(2),3)
これはPerlの非常に重要な部分であるため、「決して使用しない」としてそれを却下することはあなたに不利益をもたらします。ほぼすべての内部関数がプロトタイプを使用しているため、独自のコードでプロトタイプがどのように機能するかを理解することで、組み込み関数でプロトタイプがどのように使用されているかをよりよく理解できます。そうすれば、不要な括弧を避けることができ、より見栄えの良いコードになります。
最後に、警告する1つのアンチパターン:
package Class;
sub new ($$) { bless $_[1] }
sub method ($) { $_[0]->{whatever} }
コードをメソッド(Class->method
または$instance->method
)として呼び出す場合、プロトタイプチェックは完全に無意味です。コードをメソッドとしてしか呼び出せない場合、プロトタイプを追加するのは間違っています。これを行う人気のあるモジュールをいくつか見ましたが(こんにちは、XML::Compile
)、間違っているので、実行しないでください。渡す引数の数を文書化する場合は、次のようにします。
sub foo {
my ($self, $a, $b) = @_; # $a and $b are the bars to fooify
....
また
use MooseX::Method::Signatures;
method foo(Bar $a, Bar $b) { # fooify the bars
....
とは異なりfoo($$)
、これらは意味があり、読みやすいものです。