在 Perl 中,如何在子程序之间共享一个变量,使用严格?
Posted
技术标签:
【中文标题】在 Perl 中,如何在子程序之间共享一个变量,使用严格?【英文标题】:In Perl, how to share a variable between subroutines, with use strict? 【发布时间】:2012-09-20 14:14:36 【问题描述】:如果我不use strict;
,下面的代码可以正常工作并打印出“alice”:
assign_name();
print_name();
sub assign_name
$name = "alice";
sub print_name
print $name;
但是,当我执行use strict;
时,我知道我必须在使用变量之前声明它。我在某处读到我应该使用our
而不是my
来声明一个全局变量。所以我有以下内容:
use strict;
use warnings;
assign_name();
print_name();
sub assign_name
our $name = "alice";
sub print_name
print $name; # This is line 12.
然后我得到以下错误:
Variable "$name" is not imported at test.pl line 12.
Global symbol "$name" requires explicit package name at test.pl line 12.
Execution of test.pl aborted due to compilation errors.
请帮忙。
【问题讨论】:
你应该避免使用全局变量。它将使您的代码更易于阅读,并避免简单的错误。 我还想说,对你有好处的用户!使用strict
是一个好主意,而且当新的Perlers 发现使用它时某些东西不起作用时,他们常常很快就放弃它。很好地询问您的代码为什么不起作用并学习正确地执行它! :-)
【参考方案1】:
你应该声明全局变量upper:
use strict;
use warnings;
my $name;
assign_name();
print_name();
sub assign_name
$name = "alice";
sub print_name
print $name; # This is line 12.
【讨论】:
虽然这行得通,正如 ikegami 指出的那样,但你真的不需要在这里设置$name
全局。【参考方案2】:
只需声明两个子都可以看到的变量。
use strict;
use warnings;
my $name;
assign_name();
print_name();
sub assign_name
$name = "alice";
sub print_name
print $name;
(这里没有理由使用our
!)
【讨论】:
您能否详细说明我应该在哪里使用our
?
你的意思是“什么时候”?当你想创建一个全局变量时,即几乎从不;您总是希望尽可能地限制变量的范围。当您需要为 Perl 填充包的 @ISA
时,对于 Exporter 的包 @EXPORT_OK
大约只有两次。
我要补充一点,当您希望从其他包访问变量时,您可以使用全局变量(即our
)。几乎每次您可能想这样做时,最好使用 OO 方案重写库。 (@EXPORT_OK
是全局的原因是因为Exporter
模块检查它以确定要导出哪些符号,因此该变量必须在包外可见。)
@Joel Berger,我的想法完全正确
@memowe,不正确。 our
变量是词法范围的变量,别名为包变量。它们绝对是变量(名称和存储之间的关联)。【参考方案3】:
我知道这超出了您的问题范围,ikegami 的回答很好地回答了它,但我认为还有更多要说的。如果您有旨在更改包范围变量的函数,则可能您可以更好地将这些变量重写为对象属性。在 Perl 中,我们可以使用 Moose
来做到这一点。
#!/usr/bin/env perl
use strict;
use warnings;
# proper use of scoping, h/t tchrist
package Person;
use Moose;
use namespace::autoclean; # recommended
has 'name' => ( is => 'rw', isa => 'Str', required => 1);
__PACKAGE__->meta->make_immutable; # recommended
my $person = Person->new( name => 'Joel' );
$person->name( 'Adam' ); # change name
print $person->name . "\n";
在本例中,我们创建了一个name
属性,我们可以在对象构造期间设置它,然后更改它或使用访问器方法查看它。本来是全局的数据,在这种情况下是名称,然后包含在对象的内部数据中。这允许您的代码的不同部分重用相同的逻辑,而不必担心全局数据的状态。
【讨论】:
非常感谢您的友好回答。以上是关于在 Perl 中,如何在子程序之间共享一个变量,使用严格?的主要内容,如果未能解决你的问题,请参考以下文章