私のコードでは、次のように、関数呼び出しからパラメーターを抽出するかなり原始的な方法を使用しています。
sub addSix ($$$$$$) {
my ($a, $b, $c, $d, $e, $f) = (shift, shift, shift, shift, shift, shift);
return $a + $b + $c + $d + $e + $f;
}
print addSix (1, 2, 3, 4, 5, 6) . "\n";
(プリミティブコードを忘れてください。顕著なビットは複数のshift
呼び出しです)。
今ではそれは私にはかなり厄介に思えますが、Perlには次のようなものがあるかもしれません:
my ($a, $b, $c, $d, $e, $f) = shift (6);
または同様のもの。
しかし、私はそのようなものを見つけることができません。これに配列を使用できることはわかっていますが、それでも配列を個々のスカラーに解凍する必要があると思います。これは、6つのパラメーターが類似している上記の例の場合にはそれほど悪くはありませんが、配列として実際には適していない場合に興味があります。
shift
キーワードの泥沼に終わることなく、どのようにしてパラメーターを抽出できますか?
次のように入力するだけです。
my ($a, $b, $c, $d, $e, $f) = (@_);
そのプロトタイプがなく、そのサブが6つを超える引数で呼び出された場合、6番目以降の引数は単に「一致しません」$f
は6番目の引数に設定されます。
6番目以降のすべての引数をキャッチしたい場合は、次のように実行できます。
my ($a, $b, $c, $d, $e, $f, @others) = (@_);
スカラーのリストが右側のリストよりも長い場合、最後の要素はundef
になります。
実際の必要がない限り、プロトタイプの使用は強くお勧めしません。
Perlの場合と同様に、それを行う方法は複数あります。
渡された最初の6つのパラメーターのみを追加することを保証する1つの方法は次のとおりです。
use List::Util 'sum';
sub addSix { sum @_[0..5] }
または、自己文書化コードが好きな場合:
sub addSix {
my @firstSix = @_[0..5]; # Copy first six elements of @_
return sum @firstSix;
}
これは古いスレッドだと思いますが、複数の値をシフトするためのより良い方法を考えさせられました。これはすべてちょっとした楽しみです...主に教育目的でこれを投稿します。
確かに、_($x, $y) = @_
_を保持したい場合は_@_
_が最適ですが、何らかの理由で引数をシフトしたい場合はどうでしょうか。おそらく、_@_
_の残りの引数の数によって決定される追加のサブルーチン機能が必要です。
これを行うために私が考えることができる最もクリーンな1行の方法は、単純なマップを使用することです
_sub shiftySub {
map { $_ = shift } my ($v, $w, $x, $y);
# @_ now has up to 4 items removed
if (@_) { ... } # do stuff if arguments remain
}
_
@_
_はサブスコープで空になります。@_
_のサブスコープには1つの項目が残っています。@_
_は空であり、_$y
_はundef
です。paxdiablo の理論上のshift(6)
演算子に関しては、この操作を実行する独自の関数を作成できます。
_sub shifter (\@;$) {
my ( $array, $n ) = ( @_, 1 );
splice( @$array, 0, $n );
}
_
この関数は、参照渡しのプロトタイプ(プロトタイプを使用する必要がある非常に限られた理由の1つ)を適用して、呼び出し元のスコープ内で配列がシフトされるようにすることで機能します。次に、このように単純に使用します...
_my @items = ('one', 'two', 'three', 'four');
my ($x, $y) = shifter(@items, 2);
# or as a replacement for shift
my $z = shifter(@items)
# @items has 1 item remaining in this scope!
_
もちろん、このshifter
関数を他のサブ内で使用することもできます。このような関数の主な欠点は、演算子の両側で割り当ての数を追跡する必要があることです。
_my $post = 'informative' || 'interesting';
_を願っています