説明
はい。この構文は、Perlにとって正しく慣用的なものです。関数呼び出しのすべての部分を分析してみましょう---おそらくあなたはすでに説明の一部を知っています。
準備:入力データ
@array = (“0A0”, “005”, “001”, “004”, “0BC”, “004”, “002”, “001”);
@ranges = ();
# \@array and \@ranges are now normal scalar references.
配列への参照の概念を理解していただければ幸いです。そうでない場合は、perlreftutまたはperllolをお読みください。実際、これはあなたが求めている呼び出し構文には影響しません。ちなみに、あなたはまた書いたかもしれません:
$array_ref=[“0A0”, “005”, “001”, “004”, “0BC”, “004”, “002”, “001”];
$range_ref=[];
$numRanges = buildRanges(VALUES => $array_ref, REF_RANGES=> $range_ref);
関数呼び出し
Perlでは、矢印演算子=>は通常のコンマと同じように機能します(後で説明する小さな副作用があります)。次の呼び出しは完全に同じです。
$numRanges = buildRanges(VALUES => $array_ref, REF_RANGES => $range_ref);
$numRanges = buildRanges("VALUES", $array_ref, "REF_RANGES", $range_ref);
したがって、2つの定数文字列と2つの配列参照の4つの引数を使用して関数buildRangesを呼び出すだけです。VALUESという単語が定数文字列「VALUE」に変更されていることに気づきました。同じことがREF_RANGESという単語にも当てはまります。これは特別なルールです。矢印=>の前と中括弧{}の内側では、プレーン識別子はサイレントに文字列に変換されます。これは以下で再び見られます。ただし、$ a => $ bのような他の式はそのままで、文字列へのサイレント変換はここでは行われません。
なぜPerlがこれを行うのかと疑問に思われるかもしれません。これはシンタックスシュガーです:=>演算子は、それなしでは簡単に実行できないことは何もしません。しかし、経験豊富なperlプログラマーにとって、KEY => $valueの形式は"KEY"、$valueよりも明確に見えます。
関数の定義
関数buildRangesの定義は次のようになります(説明ではこれを使用します)。
sub buidRanges { my(%info)=@_;
my $values = $info{VALUES};
my $ref_ranges= $info{REF_RANGES};
my $special_feature = $info{SPECIAL_FEATURE}; # explained below
if($special_feature) { ... return special_result; }
... process $values and $ref_ranges ... return $numRanges.
}
入力データを使用すると、次の4行のそれぞれに同じ効果があります。
my(%info)=@_; # the actual code
my(%info)=(VALUES => \@array, REF_RANGES=> \@ranges ); # what this does
my %info; $info{"VALUES"}=\@array; $info{"REF_RANGES"}=\@ranges;
my %info; $info{ VALUES }=\@array; $info{ REF_RANGES }=\@ranges;
基本的に、入力データは各引数へのアクセスを可能にするハッシュに変換されます。関数呼び出しの定数文字列はハッシュキーになります。
理解している行を1つ選び、それを他の行と比較します。同じことを行います。詳細については、perldscを参照してください。
この場合、@_は入力引数の配列であることに注意してください
@_ = ( VALUES => \@array, REF_RANGES=> \@ranges);
@_ = ("VALUES", \@array,"REF_RANGES", \@ranges); # without syntactic sugar
$info{VALUES}が$info{"VALUES"}と同等であることに気付いたかもしれません。これも、上で説明したように、構文糖衣です。
架空の実装のさらに下では、ハッシュから入力データを引き出します。
my $values = $info{VALUES}; # i.e: my $value = \@array;
my $ref_ranges = $info{REF_RANGES}; # i.e: my $ref_renges = \@ranges;
これで、関数の実装は入力データを処理できます。
なぜこれを簡単にしないのですか?---名前付き引数
これまでのところ、同様の効果をはるかに簡単に達成できたはずです。
$numRanges = buildRanges($array_ref, $range_ref); # simpler function call
sub buidRanges { my($values, $ref_ranges)=@_;
... process $values and $ref_ranges ... return $numRanges.
}
これはおそらく、あなたがすでによく理解しているプログラミングスタイルです。
だから:なぜそれをいくつかのPerlプログラマーをより複雑にする(そしてまたはるかに遅くする)のですか?答えは次のとおりです。より柔軟性があり、自己文書化がいくらか進んでいます。
ポイントをより明確にするために、関数定義にSPECIAL_FEATUREを追加しました。これで、関数は次のように呼び出すこともできます。
$numRanges = buildRanges(VALUES => \@array, SPECIAL_FEATURE=> "infinite ranges");
実装された関数は、SPECIAL_FEATUREが要求され、REF_RANGESが提供されていないことを通知できます。
一部の高レベル関数には、場合によっては(常にではないが)役立つ追加機能が多数あるため、使用する機能と使用しない機能を呼び出し元に決定させることは非常に理にかなっています。ここでは、名前付きの引数が役立ちます。
もちろん、buildRanges関数によってどのような特別な機能が認識されるかはわかり
ません。その実装を確認するか、使用するように指示した人に依頼する必要があります。また、一般的な慣例として、一部のプロジェクトでは、特別な機能をあまり提供していない場合でも、すべての高レベル関数がこの呼び出しスタイルを使用する可能性があります。