Аргументы подпрограммы как пары ключ-значение без переменной temp
в Perl мне всегда нравился стиль пары ключ-значение передачи аргументов,
fruit( apples => red );
Я делаю это много:
sub fruit {
my %args = @_;
$args{apples}
}
чисто для компактности и имея более одного способа сделать это, есть ли способ либо:
доступ к парам ключ-значение без назначения
@_
в хэш? Т. е. в одном заявлении?аргументы подпрограммы автоматически становятся хэшем ссылка, возможно, через прототип подпрограммы?
без:
присвоение переменной temp
my %args = @_;
наличие вызывающего абонента по ссылке, т. е.
fruit({ apples => red });
чисто для эстетики
попытка
-
${%{@_}}{apples}
попытка ссылки
@_
, интерпретировать, что в качестве хэш-реф, и доступ к значению по ключу.но я получаю ошибку, что это не хэш-ссылка. (А это не так ^.^ ) Я думаю о C, где вы можете бросить указатели, среди прочего, и избежать явного переназначения.
-
Я также пробовал прототипы подпрограмм
sub fruit (%) { ... }
...но аргументы рушатся в
@_
как обычно.
2 ответов
вы не можете выполнить хэш-функция lookup (${...}{...}
) без хэша. Но вы можете создать анонимный хэш.
my $apples = ${ { @_ } }{apples};
my $oranges = ${ { @_ } }{oranges};
вы также можете использовать более простой синтаксис post-dereference
my $apples = { @_ }->{apples};
my $oranges = { @_ }->{oranges};
это было бы очень неэффективно. Вы создадите новый хэш для каждого параметра. Вот почему обычно используется именованный хэш.
my %args = @_;
my $apples = $args{apples};
my $oranges = $args{oranges};
альтернативой, однако, было бы использовать хэш-срез.
my ($apples, $oranges) = @{ { @_ } }{qw( apples oranges )};
следующий версия post-derefence, но она доступна только в 5.24+[1]:
my ($apples, $oranges) = { @_ }->@{qw( apples oranges )};
-
он доступен в 5.20+, если вы используете следующее:
use feature qw( postderef ); no warnings qw( experimental::postderef );
если вы больше обеспокоены компактностью, чем эффективностью, вы можете сделать это следующим образом:
sub fruit {
print( +{@_}->{apples}, "\n" );
my $y = {@_}->{pears};
print("$y\n");
}
fruit(apples => 'red', pears => 'green');
причина +{@_}->{apples}
вместо {@_}->{apples}
это то, что он конфликтует с print BLOCK LIST
синтаксис print
без него (или каких-либо других средств устранения неоднозначности).