在 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 中,如何在子程序之间共享一个变量,使用严格?的主要内容,如果未能解决你的问题,请参考以下文章

perl中my变量和local变量之间的区别

如何在不同文件中的史诗之间共享变量?

Perl:在线程之间共享复杂的数据结构

如何在c中制作共享内存?

Flask 中的全局变量是线程安全的吗?如何在请求之间共享数据?

如何在 fork() 创建的进程之间共享内存?