在同一语句中使用 shift 和 @_ 是否安全?

Is it safe to use shift and @_ in the same statement?

下面的代码安全吗?它是否在所有 perl 版本 >= 5.8 上 运行?是否保证 shifts@_ 解包之前执行?

sub f1 {
    shift->update(p1 => shift, p2 => shift, @_);
}

详细的替代代码:

sub f2 {
    my ($self, $p1, $p2, @r) = @_;
    $self->update(p1 => $p1, p2 => $p2, @r);
}

它在所有现有的 Perl 解释器中都能正常运行。

但是,当逗号运算符在标量上下文中使用时,它的操作数评估顺序被记录下来,但当它在列表上下文中使用时没有记录,就像这里的情况一样。更糟糕的是,它是某个区域中未记录的行为,而在某些其他语言中是未定义的行为。我没有看到行为发生变化,但它也不是完全安全的。

妥协:

sub f3 {
    my $self = shift;
    my $p1   = shift;
    my $p2   = shift;

    $self->update(p1 => $p1, p2 => $p2, @_);
}

如果您绝对想使用无变量,您可以安全地使用以下内容:

sub f4 { $_[0]->update(p1 => $_[1], p2 => $_[2], @_[3..$#_]) }

不过我不知道您为什么要使用它。即使不计算命名参数的自记录属性的损失,也很难阅读。