gpt4 book ai didi

perl - 需要帮助了解 Perl 5 如何解析引用相同变量的复合赋值语句

转载 作者:行者123 更新时间:2023-12-02 08:00:56 24 4
gpt4 key购买 nike

我需要了解如何评估这个简单的表达式,因为结果与我预期的不一样。

我对 Perl 很陌生,但我认为我有足够的理解来解释这个看似简单的片段的结果。显然我错过了一些东西。
我已经使用 Deparse 来查看 Perl 是如何处理表达式的,而 Deparse 并没有改变我已有的括号。

$i = 12;
$i = (($i /= 2) + ($i = 100));
print $i;

根据我的理解,结果应该是 106,假设表达式按照括号指示的顺序进行评估,并且看起来应该是这样。我会认为:
$i 首先除以 2,从而将 6 分配给 $i,得到值 6。然后将 100 分配给 $i,100 是第二个表达式的结果。 6 + 100 = 106,我认为最终会分配给 $i。
相反,它会打印 "200"。

在 PHP 中,同样的代码确实会产生“106”,这让我相信这与表达式的某些部分被解释为列表有关,或者与 Perl 一样精彩的东西有关。
迫不及待地想知道我做错了什么。

最佳答案

到目前为止,大多数语言都没有定义当您在单个表达式中读取和写入相同的值变量时会发生什么。 Perl 也不异常(exception)。您发布的表达式没有定义的结果。

这记录在 perlop 中:

modifying a variable twice in the same statement will lead to undefined behavior. Avoid statements like:

    $i = $i ++;
print ++ $i + $i ++;


发生的事情是 $i /= 2$i = 100两者都返回 $i —不是 $i 的值, 但是 $i本身——所以你最终会做 $i + $i而不是 6 + 100 .你不能指望这种行为。此外,Perl 碰巧先计算加法的左操作数,然后再计算右操作数——这是你不能指望的其他事情——所以 $i100是时候执行加法了。

如果有人想鬼混,这里是当前 perl 时发生的事情的再现。评估 OP 的代码:
use strict;
use warnings;
use feature qw( say );
use experimental qw( refaliasing declared_refs );

my $i = 12;

my @ST; # Stack
{ \$ST[@ST] = \( $i ); }
{ \$ST[@ST] = \( 2 ); }
{ \my ($lhs, $rhs) = \splice(@ST, -2); \$ST[@ST] = \( $lhs /= $rhs ); }
{ \$ST[@ST] = \( 100 ); }
{ \$ST[@ST] = \( $i ); }
{ \my ($rhs, $lhs) = \splice(@ST, -2); \$ST[@ST] = \( $lhs = $rhs ); }
{ \my ($lhs, $rhs) = \splice(@ST, -2); \$ST[@ST] = \( my $sum = $lhs + $rhs ); }
{ \$ST[@ST] = \( $i ); }
{ \my ($rhs, $lhs) = \splice(@ST, -2); \$ST[@ST] = \( $lhs = $rhs ); }

say $i; # 200

如果你使用 Devel::Peek 的 Dump ,您会注意到上面的大多数变量具有相同的地址。它们就是我们在 Perl 行话中所说的“别名”。

以下使用引用代替(尽管实际上没有创建实际引用):
use strict;
use warnings;
use feature qw( say );

my $i = 12;

my @ST; # Stack
{ push @ST, \( $i ); }
{ push @ST, \( 2 ); }
{ my ($lhs_p, $rhs_p) = splice(@ST, -2); push @ST, \( $$lhs_p /= $$rhs_p ); }
{ push @ST, \( 100 ); }
{ push @ST, \( $i ); }
{ my ($rhs_p, $lhs_p) = splice(@ST, -2); push @ST, \( $$lhs_p = $$rhs_p ); }
{ my ($lhs_p, $rhs_p) = splice(@ST, -2); push @ST, \( my $sum = $$lhs_p + $$rhs_p ); }
{ push @ST, \( $i ); }
{ my ($rhs_p, $lhs_p) = splice(@ST, -2); push @ST, \( $$lhs_p = $$rhs_p ); }

say $i; # 200

关于perl - 需要帮助了解 Perl 5 如何解析引用相同变量的复合赋值语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57468346/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com