【问题标题】:Why does Perl create an empty array reference via grep?为什么 Perl 通过 grep 创建一个空数组引用?
【发布时间】:2014-08-29 03:26:49
【问题描述】:

我可能遗漏了一些明显的东西,但我不知道为什么下面的 Perl 通过 grep 创建数组引用,而不是 sort 或其他一般引用?

print @$arr; # no output
print ref $arr; # no output
print scalar @$arr; # no output
print ref $arr; # no output
print sort @$arr; # no output
print ref $arr; # no output
print grep { 0 } @$arr; # no output
print ref $arr; # ARRAY

我可能遗漏了一些明显的东西,或者可能只是其中之一,但这让我很困惑,我想知道是否有人知道答案......

我已经在 Perl 5.8 和 5.10 上对此进行了测试,并且在两者上都获得了相同的行为。

【问题讨论】:

  • 我认为你所拥有的是 Perl 中的一个错误。
  • ...但我认为这绝不是 Perl 中的错误!
  • 请注意,scalar 导致绝对没有代码。它只是更改其操作数上的上下文标志。这是最不寻常的功能之一,所以不是一个很好的例子!
  • 哦,Perl 有plenty of bugs :-)
  • 啊,有道理。我最初认为它是取消引用 undef 值导致创建数组,但很惊讶之前没有看到这个......

标签: perl


【解决方案1】:

有趣的问题是为什么其他人不这样做。如果操作数是 undef,则在左值上下文中解引用将自动激活操作数。

$ perl -E'@$arr = "b"; say $arr // "[undef]"'
ARRAY(0x335b558)

参数总是通过引用传递给 subs,因此它们在左值上下文中进行评估。

$ perl -E'sub f { }  f( @$arr ); say $arr // "[undef]"'
ARRAY(0x284e9f8)    

但是 perlfunc 中的“函数”实际上是运算符,因此,它们可以发明自己的语法和调用约定。 Perl 知道sort 在使用默认比较函数时不会修改其操作数,因此它不会在左值上下文中计算它们。

$ perl -E'sort @$arr; say $arr // "[undef]"'
[undef]

grep$_ 别名为传递给它的每个项目,因此它的参数可以修改(尽管这通常不是一个好主意),因此它的参数在左值上下文中进行评估。

$ perl -E'@a = "a"; grep { $_ = uc($_) } @a; say @a'
A

【讨论】:

  • formap 也是如此,所以很明显你正在做某事。代码块本身似乎无关紧要,$_ 的别名似乎就足够了。
  • 有趣,我没想到for/map,知道我错过了一些额外的测试。这让我们在新功能构建期间遇到了检查,这绝对令人困惑!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 2022-01-25
相关资源
最近更新 更多