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

Posted

技术标签:

【中文标题】在同一个语句中使用 shift 和 @_ 是不是安全?【英文标题】:Is it safe to use shift and @_ in the same statement?在同一个语句中使用 shift 和 @_ 是否安全? 【发布时间】:2015-07-06 21:59:52 【问题描述】:

下面的代码安全吗?它是否在所有 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);

【问题讨论】:

除非你想在高尔夫上取胜,否则就做详细的。 【参考方案1】:

它在所有现有的 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..$#_]) 

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

【讨论】:

我只记得 perl6 有这种明确的未定义行为能够并行化它,但我看不到 perl5 有任何机会从左到右对参数列表进行评估。

以上是关于在同一个语句中使用 shift 和 @_ 是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

48Navicat的使用

48Navicat的使用

您是不是需要使用 __name__=__main__ 语句在 python 中运行任何脚本? [复制]

shell变量------shift

遇到问题如何使用 if 语句来确定某物是不是在列表中。 Python [重复]

idea 多行注释 Ctrl shift / 失效问题