为什么 Perl 中的默认范围行为是这样的?

Rya*_*ard 5 perl scope language-design

我正在为学校学习 Perl,目前正在学习my关键字的使用和 Perl 中的范围界定。(作为参考,我正在查看如何在 Perl 中使用“我的”关键字?

在我看来,C 风格的默认作用域最有意义……您在块内声明一个变量,该变量存在于该块内,一旦离开该块,该变量将不再可访问。为什么在 Perl 中,要指定这种行为,必须使用my关键字?似乎将变量的范围限制在使用它的地方将是良好的标准行为,并且一直使用my似乎非常多余,并且会导致代码混乱。

似乎有点像走进杂货店,在继续购物之前立即大声宣布您喜欢的某某品牌,以防万一您周围的人好奇(他们可能不是)。

(可能重复,这个问题可能会被删除......为什么在文件范围内用“my”声明 Perl 变量?。)

ike*_*ami 9

如果你想要词法范围的变量,你需要某种形式的声明。[1]


在我看来,C 风格的默认作用域最有意义……你在一个块内声明一个变量,该变量存在于该块内,一旦你离开该块,该变量就不再可访问

正是它在 Perl 中的工作方式。int i在 C 中使用声明变量的地方,my $i在 Perl 中使用。两者都创建了一个词法范围的变量,也就是说一个只在当前块和包含的块中可见的变量。在块外执行代码时,变量不可访问。Perl 中变量的作用域与 C 中变量的作用域相同。[2]

// Can't use `i` here.           # Can't use `$i` here.
{                                {
   // Can't use `i` here.           # Can't use `$i` here.
   int i = 4;                       my $i = 4;
   printf("%d\n", i);       4       say $i;
   {                                {
      printf("%d\n", i);    4          say $i;
      int i = 5;                       my $i = 5;
      printf("%d\n", i);    5          say $i;
   }                                }
   printf("%d\n", i);       4       say $i;
}                                }
// Can't use `i` here.           # Can't use `$i` here.
Run Code Online (Sandbox Code Playgroud)
  1. Python 没有显式的变量声明,但它也没有词法范围的变量;Python 变量是函数作用域的。

  2. 但是,变量的生命周期是不一样的。标量可以在它驻留在 Perl 中的块的末尾之后保持活动状态,但对于 C 中的类似变量(具有“自动存储持续时间”的变量)而言,情况并非如此。

    例如,

    # You can't use `@a` outside of the sub,
    # But you can use the created array anonymously.
    sub f { my @a = qw( abc def ); return \@a; }
    
    Run Code Online (Sandbox Code Playgroud)

    从这个意义上说,my $x更类似于动态分配的结构。


Sch*_*ern 6

因为这就是 Larry Wall 在 1987 年所做的,而 Perl 5 仍然与该决定向后兼容。词法变量直到 1994 年的 Perl 5 才被引入,到那时已经有相当大的 Perl 4 程序安装基础。

我会推测为什么。Perl 并没有被设想为一种应用程序语言,它成为了一种应用程序语言。Perl 1 于 1987 年编写,是sedawkBourne shell的更强大的替代品。

如果您有一个问题,通常会使用 sed 或 awk 或 sh,但它超出了它们的能力或必须运行得更快一点,并且您不想用 C 编写愚蠢的东西,那么 perl 可能适合您。

来自 Perl 1.0 手册

sed 和 awk 程序通常只有一行。并且在 shell 中变量是全局的。鉴于 Perl 1 的目的,这很好。

在过去的几十年中,公认的软件工程标准发生了很大变化。当系统更小更简单时,全局变量更容易被接受。随着复杂性的增加,全局变量越来越危险。

  • 这就说得通了。了解了 Perl 作为 sed/awk/sh 替代品的背景(早期历史),我可以看到它是如何发展的。我想在某个时候,有人说“嘿,如果我想要非全局变量怎么办?” 他们想出了一种仍然允许向后兼容的方法(“my``”关键字)。 (2认同)