Как получить несколько аргументов в функциях Perl?
в моем коде я использую довольно примитивный метод извлечения параметров из вызова функции следующим образом:
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";
(забудьте примитивный код, выделяющийся бит-это multiple shift
вызовы).
теперь это кажется мне довольно грязным, и я, хотя Perl может иметь что-то вроде:
my ($a, $b, $c, $d, $e, $f) = shift (6);
или что-то подобное.
но я не могу найти ничего подобного. Я знаю, что могу использовать массивы для этого, но я думаю, что мне все равно придется распаковать массив в отдельные скаляры. Это было бы неплохо для примера выше, где шесть параметров похожи, но меня больше интересует случай, когда они не подходят в качестве массива.
как вы можете извлечь параметры, не заканчивая болотом shift
ключевые слова?
3 ответов
вы можете просто ввести:
my ($a, $b, $c, $d, $e, $f) = (@_);
если у вас не было этого прототипа, и если эта суб была вызвана с более чем шестью аргументами, те, что после шестого, просто "не совпадают",$f
будет установлен в шестой аргумент.
если вы хотите поймать все аргументы после шестого, вы можете сделать это так.
my ($a, $b, $c, $d, $e, $f, @others) = (@_);
если ваш список скаляров длиннее, чем список справа, последние элементы будут undef
.
использование прототипов очень не рекомендуется, если нет реальные потребность в нем.
Как всегда с Perl, есть несколько способов сделать это.
вот один из способов гарантировать добавление только первых шести параметров, которые передаются:
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) = @_
отлично, если вы хотите сохранить @_
, но, возможно, вы по какой-то причине хотите изменить свои аргументы? Возможно, вам нужна дополнительная функциональность подпрограммы, определяемая количеством оставшихся аргументов в @_
.
самый чистый однострочный способ, который я мог подумайте, чтобы сделать это с помощью простой карты
sub shiftySub {
map { $_ = shift } my ($v, $w, $x, $y);
# @_ now has up to 4 items removed
if (@_) { ... } # do stuff if arguments remain
}
- если представлено 4 аргумента,
@_
теперь пусто в подпространстве. - если представлено 5 аргументов,
@_
имеет 1 элемент, остающийся в области sub. - если приведены 3 аргумента,
@_
пусто, и$y
isundef
в подразделе масштаб.
о paxdiablo'ы теоретические shift(6)
оператор, мы смогли создать нашу собственную функцию который выполняет эту операцию...
sub shifter (\@;$) {
my ( $array, $n ) = ( @_, 1 );
splice( @$array, 0, $n );
}
функция работает, применяя прототип pass-by-ref (одна из очень ограниченных причин, по которой вы должны когда-либо использовать прототипы), чтобы обеспечить смещение массива в области вызова. Затем вы используете его просто так...
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';