为什么在文件范围内用“my”声明 Perl 变量?

Don*_*kby 5 perl scope

我正在学习 Perl 并试图了解变量范围。我知道这my $name = 'Bob';在 sub 中声明一个局部变量,但是为什么要my在全局范围内使用关键字?这只是一个好习惯,所以您可以安全地将代码移动到子程序中吗?

我看到很多这样做的示例脚本,我想知道为什么。即使使用use strict,当我删除my. 我试过比较有和没有它的行为,我看不出有什么区别。

这是执行此操作的一个示例

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

use DBI;

my $dbfile = "sample.db";

my $dsn      = "dbi:SQLite:dbname=$dbfile";
my $user     = "";
my $password = "";
my $dbh = DBI->connect($dsn, $user, $password, {
   PrintError       => 0,
   RaiseError       => 1,
   AutoCommit       => 1,
   FetchHashKeyName => 'NAME_lc',
});

# ...

$dbh->disconnect;
Run Code Online (Sandbox Code Playgroud)

更新

当我测试这种行为时,我似乎很不走运。这是我测试的脚本:

use strict;

my $a = 5;
$b = 6;

sub print_stuff() {
    print $a, $b, "\n"; # prints 56
    $a = 55;
    $b = 66;
}

print_stuff();
print $a, $b, "\n"; # prints 5566
Run Code Online (Sandbox Code Playgroud)

正如我从这里的一些答案中了解到的那样,$a并且$b是已经声明的特殊变量,因此编译器不会抱怨。如果我将该脚本中的$bto更改为$c,则它会抱怨。

至于为什么my $foo在全局范围内使用,似乎文件范围实际上可能不是全局范围。

小智 2

这只是一个很好的做法。作为个人规则,我尝试将变量保持在尽可能小的范围内。如果一行代码看不到变量,那么它就不会以意想不到的方式弄乱它。

我很惊讶你发现脚本在use strict没有 的情况my下也能工作。这通常是不允许的:

$ perl -E 'use strict; $db = "foo"; say $db'
Global symbol "$db" requires explicit package name at -e line 1.
Global symbol "$db" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.
$ perl -E 'use strict; my $db = "foo"; say $db'
foo
Run Code Online (Sandbox Code Playgroud)

变量$a$b被豁免:

$ perl -E 'use strict; $b = "foo"; say $b'
foo
Run Code Online (Sandbox Code Playgroud)

但我不知道如何使您发布的代码在 strict 和丢失的情况下工作my

  • 只有“$a”和“$b”(在“sort”调用中是特殊的)可以豁免。 (9认同)