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

时间:2014-06-20 19:02:18

标签: perl scope

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

我看到很多这样做的示例脚本,我想知道为什么。即使使用use strict,我删除my时也不会抱怨。我尝试过比较行为与否,我看不出有什么不同。

这里one example执行此操作:

#!/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;

更新

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

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

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

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

4 个答案:

答案 0 :(得分:3)

添加my是关于Perl发生过的最好的事情,它解决的问题是错别字。

假设你有一个变量$variable。您可以对此变量进行一些分配和比较。

$variable = 5;

# intervening assignments and calculations...

if ( $varable + 20 > 25 ) # don't use magic numbers in real code
{
    # do one thing
}
else
{
    # do something else
}

如果您不use strict;并要求使用my声明变量,您是否看到上述代码中的细微错误? # do one thing案例永远不会发生。我在必须维护的生产代码中遇到过这几次。

答案 1 :(得分: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

变量$a$b可免除:

$ perl -E 'use strict; $b = "foo"; say $b'
foo

但我不知道如何让您发布的代码使用严格且缺少my

答案 2 :(得分:2)

几点:

  • strict要求所有变量都使用my(或state)声明或安装到包中 - 使用our语句声明或use vars pragma(古老),或在编译时插入符号表。

  • 他们是该文件的变量。对于使用该文件期间所需的任何模块,它们仍然无关紧要且无用。

  • 它们可以跨包使用(虽然这是一个不太好的理由。)

  • 词汇变量没有任何唯一替代方法的魔力。在更改范围时,不能“推”和“弹出”词法变量,就像使用任何包变量一样。没有魔法意味着更快更平稳的处理。

  • 懒惰。声明my没有括号,而不是通过特定的包围来集中范围,这更容易。

    {   my $visible_in_this_scope_only;
        ...
        sub bananas {
            ...
            my $bananas = $visible_in_this_scope_only + 3;
            ...
        }
    } # End $visible_in_this_scope_only
    

(注意语法:在我的代码中,我从不使用裸支撑。它总是会告诉你,在标准循环之前或之后,即使它是“显而易见的”。

答案 3 :(得分:1)

sub控制/限制定义其操作的大括号{}之间的变量范围。当然,许多变量存在于特定函数之外,并使用词汇my来表示"全局"变量可以让你更好地控制"动态"他们的行为在你的申请中。 Private Variables via my() perlsubperlodoc部分详细讨论了这样做的原因。

我要从elsewhere引用自己,这不是最好的事情,但这里有:

  

经典 perlmonks 节点 - Variable Scoping in Perl: the basics - 经常出现   咨询参考: - )

正如我在评论中所指出的,布鲁斯格雷在YAPC :: NA 2012的演讲 - The why of my()是一个很好的故事,关于一位非常专业的perl程序员如何围绕perl和命名空间。

我听说过人们将my解释为Perl等同于Javascript' var - 它实际上是必要的,但Perl是{{1}如果你坚持或努力去做,事情会在没有它的情况下发挥作用。

ps:实际上使用Javascript,我猜函数 用于控制"范围"与您在perl中使用my的描述类似的方式。