我可以在 perl 子原型中使变量可选吗?

Can I make a variable optional in a perl sub prototype?

我想了解是否可以在其中包含子原型 可选参数。使用原型我可以做到这一点:

sub some_sub (\@\@\@) {
    ...
}

my @foo = qw/a b c/;
my @bar = qw/1 2 3/;
my @baz = qw/X Y Z/;

some_sub(@foo, @bar, @baz);

这很好,可读性强,但我尝试这样做的那一刻

some_sub(@foo, @bar);

甚至

some_sub(@foo, @bar, ());

我收到错误:

Not enough arguments for main::some_sub at tablify.pl line 72, near "@bar)"

Type of arg 3 to main::some_sub must be array (not stub) at tablify.pl line 72, near "))"

是否可以有一个原型 可变数量的参数?还是可以通过签名实现类似的东西?

我知道可以通过始终传递 arrayrefs 来完成我想知道是否还有其他方法。毕竟TMTOWTDI.

分号后的所有参数都是可选的:

sub some_sub(\@\@;\@) {
}

大多数人都希望您的论点列表变平,而您正在使用一种过时的工具来完成人们不期望的事情。

相反,通过引用传递数据结构:

some_sub( \@array1, \@array2 );

sub some_sub {
   my @args = @_;
   say "Array 1 has " . $args[0]->@* . " elements";
   }

如果你想在 sub 中使用这些命名数组,你可以使用 ref aliasing

use v5.22;
use experimental qw(ref_aliasing);
sub some_sub {
    \my( @array1 ) = $_[0];
    ...
    }

在 v5.26 中,您可以将引用运算符移到括号内:

use v5.26;
use experimental qw(declared_refs);
sub some_sub {
    my( \@array1 ) = $_[0];
    ...
    }

并且,请记住 v5.20 引入了 :prototype 属性,因此您可以区分原型和签名:

use v5.20;

sub some_sub :prototype(@@;@) { ... }

我在 The Effective Perler (which you already read, I see), in Perl New Features, a little bit in Preparing for Perl 7 上写了这些事情(主要是关于你需要停止在 Perl 5 中做的事情以保证未来的发展)。