我可以在perl的子例程中声明全局变量吗?

Eri*_*ett 1 perl scope global-variables

我可以在perl的子例程中声明全局变量use strict吗?

请考虑以下代码:

#!/usr/bin/perl
# $Id: foo,v 1.5 2019/02/21 10:41:08 bennett Exp bennett $

use strict;
use warnings;

initialize();

print "$lorem\n";

exit 0;

sub initialize {
    # How would one delcare "$lorem" here such that it is available as
    # a global?

    $lorem = <<_EOM_
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
_EOM_
    ;
}
Run Code Online (Sandbox Code Playgroud)

请注意,我不是问(ab)以这种方式使用全局变量是一个好主意; 我确定不是.

我试过几个组合our$main::,但他们都在短短的方式失败,你可能会想到他们.

在这一点上,我只是好奇.可以吗?

谢谢.

-E

我想知道是否有一些带BEGIN阻挡的恶作剧会起作用.

更新澄清答案:

#!/usr/bin/perl
# $Id: foo,v 1.7 2019/02/21 19:48:26 bennett Exp bennett $

use strict;
use warnings;

initialize();

printf("$main::lorem\n");

exit 0;

sub initialize {
    # How would one delcare "$lorem" here such that is is available as
    # a global-ish?

    our $lorem = <<_EOM_
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
_EOM_
    ;
}
Run Code Online (Sandbox Code Playgroud)

这将有效,但正如@simbabque指出的那样,这很丑陋.

感谢大家.

-E

sim*_*que 5

对于您的具体示例,您不需要全局变量.

Perl有包变量.这些是使用创建的,our也可以使用它们访问$namespace::(main默认命名空间在哪里,也$::适用于此).那些是全球性的,但我们很少称之为.

你需要记住,它our是一个词法别名,所以如果你在sub中声明它,它将无法在外面使用,因为在更大的范围内没有词法别名.

use strict;

sub foo {
    our $bar = 123;
}

foo();
print $bar; # error
Run Code Online (Sandbox Code Playgroud)

您需要在更大的范围内声明变量.

use strict;

our $bar;

sub foo {
    $bar = 123;
}

foo();
print $bar;
Run Code Online (Sandbox Code Playgroud)

这将起作用,因为$bar现在可以在文件的范围内使用.

所有这些仅在use strict打开时适用.如果您没有声明变量,它将自动成为包变量.但是,如果启用strict,则必须声明所有变量.因此,您需要明确.

my如果您在sub之外声明它,也可以使用它.

use strict;

my $bar;

sub foo {
    $bar = 123;
}

foo();
print $bar;
Run Code Online (Sandbox Code Playgroud)

由于您在脚本中执行此操作并且没有明确的包声明,因此我认为可以安全地假设不涉及其他模块.在这种情况下,使用my或者无关紧要our.

如果您在包含不同文件的包中使用它,那将会产生影响.在文件范围内声明的变量my私有的,因为无法直接从外部访问它们.

package Foo;
use strict;

my $bar = 123;

### other file
use Foo;

# no way to get $bar as there is no $Foo::bar
Run Code Online (Sandbox Code Playgroud)

但是如果你使用our(或过时use vars)它将成为一个包变量.

package Foo;
use strict;

our $bar = 123;

### other file

use Foo;
print $Foo::bar;
Run Code Online (Sandbox Code Playgroud)

我可以在Perl的子程序中声明全局变量吗?

是的,您可以在子例程中声明包变量our.但是你不能在它们声明的范围之外作为词法变量访问它们,所以你需要使用它们的完全限定的包名来访问它们,这很难看.