为什么Perl的严格模式允许您在此foreach上下文中取消引用具有未定义值的变量,但不能在赋值上下文中取消引用?

时间:2017-08-17 23:45:30

标签: perl

此代码:

#!/usr/bin/perl
use 5.18.0;
use strict;

# Part 1
my $undef = undef;
print "1 $undef\n";
foreach my $index (@$undef) {
  print "unreachable with no crash\n";
}
print "2 $undef\n";

# Part 2
my $undef = undef;
my @array = @$undef;
print "unreachable with crash\n";

输出:

1 
2 ARRAY(0x7faefa803ee8)
Can't use an undefined value as an ARRAY reference at /tmp/perlfile line 12.

关于第1部分的问题:

  1. 为什么第1部分中的解除引用$undef会将$undef更改为数组引用为空数组?
  2. 是否有其他上下文(除了foreach)解除引用$undef会以同样的方式更改它?描述最通用的此类案例的术语是什么?
  3. 关于第2部分的问题:

    1. 为什么在第2部分中取消引用$undef会与strict发生冲突?
    2. 是否还有其他情境(分配除外)解除引用$undef会与strict发生冲突。描述最通用的此类案例的术语是什么?

2 个答案:

答案 0 :(得分:4)

1)Perl中的for()将其操作数置于“l值上下文”中,因此$undef作为具有零元素的数组(引用)存在auto-vivified(请参阅关于l值上下文的this相对类似的问题/答案)。

3)因为你试图强制性地将一个未定义的值分配给r值上下文中的其他东西,并且这在strict下是非法的(在这种情况下没有任何东西会自动生存,所以你不是神奇地从没有任何东西创建变量就像你在l值操作中那样。)

就问题2和问题4而言,还有其他一些背景,太多不能想到我的头脑。对于2,可以想到map(),或者将操作数视为l值的任何其他操作。

答案 1 :(得分:2)

当您在左值上下文中取消引用未定义的变量时,Perl将自动生成引用及其引用的引用。

例如,

@$ref = qw( a b c );

装置

@{ $ref //= [] } = qw( a b c );

当您在rvalue上下文中取消引用未定义的变量时,Perl将不会自动生成。在严格的参考下,这是一个错误。否则,将undefined字符串化(带有警告)到空字符串,该字符串用作符号引用。

例如,

no strict qw( refs ); my $ref; my @a = @$ref;

相当于

no strict qw( refs ); my @a = @{""};

(除了后者没有警告。)

左值上下文提供给:

  • 作业的左手参数。 (这是“左值”中的“L”。)
  • 子调用和方法调用的参数(由于@_元素的别名)。
  • Foreach的列表(因为$_的别名)。
  • 某些命名运算符的操作数(例如mapgrep,因为$_的别名)。
相关问题