Предостережения, связанные с прототипами, принятыми и не считающимися c, могут ли две поддублированные подписи существовать внутри одного и того же пакета, то есть для предоставления необязательного параметра блока, такого как sort
?Подпрограммы, которые принимают необязательный параметр блока
sub myprint {
for (@_) {
print "$_\n";
}
}
sub myprint (&@) {
my $block = shift;
for (@_) {
print $block->() . "\n";
}
}
Целью является обеспечить аналогичное соглашение о вызовах, как, например sort
разрешить выполнение:
my @x = qw(foo bar baz);
print_list @x;
# foo
# bar
# baz
... и:
my @y = ({a=>'foo'}, {a=>'bar'}, {a=>'baz'});
print_list { $_->{a} } @y;
# foo
# bar
# baz
я переопределить и/или предупреждения несоответствия прототипа, если я стараюсь (что разумно).
Я полагаю, что я могу сделать:
sub myprint {
my $block = undef;
$block = shift if @_ && ref($_[0]) eq 'CODE';
for (@_) {
print (defined($block) ? $block->() : $_) . "\n";
}
}
... но &@
прототип обеспечивает синтаксический сахар; удаление требует:
my @y = ({a=>'foo'}, {a=>'bar'}, {a=>'baz'});
print_list sub { $_->{a} }, @y; # note the extra sub and comma
(я пытался ;&@
, но безрезультатно - она по-прежнему дает Type of arg 1 to main::myprint must be block or sub {} (not private array)
.)
Nice Post. Я обсуждаю, должен ли я даже попытаться понять ваш код. Возможно, сохраните его для проекта на выходные. – Miller
Может быть, я должен добавить еще несколько комментариев, чтобы показать, что происходит ... – tobyink
Интересный материал, хотя бы для того, чтобы напомнить/убедить меня в двух вещах: (1) Perl больше, чем я когда-либо запомню; и (2) два разных метода не так уж важны для сделки! Я представлю версию с прототипом с блоком как «myprint_over» и имею «sub myprint» {return myprint_over {$ _} @_; } '. Благодарю. – jimbobmcgee