0

我对另一个子程序无法访问的子程序的变量有疑问。

第一个子程序:

sub esr_info {
    my $esr ;
    my @vpls = () ;
    my @sap = ();
    my @spoke = () ;
    &conf_esr($esr , 1);
}

第二 :

sub conf_esr {
     my $e = @_[0] ;
     some code (@vpls, @sap, @spoke);
}

第一个调用第二个,我需要第一个的变量是本地的,而不是整个代码的全局变量(用于线程目的)。第二个使用第一个的所有变量。我收到这些错误:

全局符号“$esr”在 w.pl 第 63 行需要明确的包名称(您是否忘记声明“my $esr”?)。

全局符号“@vpls”在 w.pl 第 74 行需要明确的包名称(您是否忘记声明“my @vpls”?)。

我的问题:一个子例程可以访问另一个变量而不将这些变量声明为全局变量吗?

非常感谢您阅读这篇文章。

4

2 回答 2

1

您可以通过引入范围来包含(限制可见性)两个子变量的变量{ ... },例如:

{ 
    my $esr ;
    my @vpls = () ;
    my @sap = ();
    my @spoke = () ;

    sub esr_info {
        conf_esr($esr , 1);
    }

    sub conf_esr {
        my $e = @_[0] ;
        #some code (@vpls, @sap, @spoke);
    }
}

但请注意,这些变量现在在 subs 退出后保留值(它们成为状态变量)。这也称为闭包。

但是根据您的情况,其他方法可能更合适(闭包会使代码更难阅读并因此更难维护)。例如,替代方案可能是:

  • 您可以将对变量的引用作为参数传递给conf_esr,或者更好
  • 使用面向对象的方法,其中变量包含在$self哈希中。
于 2019-09-09T09:26:30.857 回答
0

我的问题:一个子例程可以访问另一个变量而不将这些变量声明为全局变量吗?

不,你应该尝试传入变量,这是更好的形式,但你也可以使用全局变量。

my $i=1;
mysub(); # This will not change the global $i
print "i=$i\n"; # This should print '1'
exit;

##########
sub mysub
{my $i=2; # This is a variable local to mysub() only.
return;
}

输入上面的代码并用 Perl 运行它。请注意,子例程mysub()中的 $i 与程序本身中的全局 $i 完全不同,因为其中的 $imysub()是不同的内存地址。

现在让我们将 $i 更改为全局。mysub()将更改全局 $i 因为它没有声明本地 $i 。

my $i=1;
mysub(); # This will not change the global $i
print "i=$i\n"; # This should print '2'
exit;

##########
sub mysub
{$i=2; # This is changing the value in the global $i memory area. 
return;
}
于 2019-09-09T16:22:34.140 回答