我正在学习 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
是已经声明的特殊变量,因此编译器不会抱怨。如果我将该脚本中的$b
to更改为$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
。