在没有全局变量名冲突,声明子程序外或传递参数的子程序之间共享变量

时间:2017-02-12 22:45:30

标签: perl

我如何将在一个子例程中声明的变量共享到另一个子例程,在其中调用,没有具有全局变量名称冲突,或者在母调用者子例程之外声明变量,或者使用任何子例程参数Δ

换句话说: 如何从子程序中调用子程序中定义的变量?

更多解释 (如果之前的单行问题不够具有描述性)

请注意,您无需阅读以理解我的问题。如果你有我要求的节省时间的话,请停止阅读。

假设我有subroutine1subroutine2

subroutine1 ();

sub subroutine1 {
  my $word1='hello';
  subroutine2();
}

sub subroutine2 {
  print $word1; #Prints nothing as subroutine2 is unable to access $word1 declared in subroutine1
}

我的问题,具体来说,询问我如何将一个子例程($word1)中声明的变量(subroutine1)共享给另一个子例程(subroutine2),在其中调用(在subroutine2)内调用subroutine1,...

  • 没有全局变量名称冲突 - 这将让我自由地命名我的变量简单名称。
  • 没有在母调用者子例程(subroutine1
  • 之外声明变量
  • 不使用任何子程序参数

例如我们可以使用以下三种简单的方法之一来实现它:

方式1:$word1声明为全球。

subroutine1 ();
sub subroutine1 {
  $word1='hello'; #$word1 is declared as global
  subroutine2();
}
sub subroutine2 {
  print $word1;
}

方式2:在母调用者子例程$word1之外声明subroutine1并限制其范围。

{
  my $word1='hello';
  subroutine1 ();
  sub subroutine1 {
    subroutine2();
  }
  sub subroutine2 {
    print $word1;
  }
}

方式3:$word1作为参数传递给subroutine2

subroutine1 ();

sub subroutine1 {
  my $word1='hello';
  subroutine2($word1);
}
sub subroutine2 {
  my $x = shift;
  print $x;
}

这个例子非常简单,可以用任何简单的方法解决,包括上面三个。但是以这种方式构建它并简单地考虑这些限制(没有全局变量名称冲突没有子程序外声明没有参数使用)肯定会解决我现在无法简化的真正复杂的问题。

1 个答案:

答案 0 :(得分:3)

如果两个子程序没有嵌套,那么根据定义你的请求是不可能的。如果它由两个非嵌套的潜艇可见,那么它必须存在于潜艇之外。因此,它必须是全局的,或者在subs之外的声明必须将其可见性限制在包含两个sub的某些词法范围。

这样就留下了嵌套的潜艇。

sub tree_visitor {
   my @rv;

   local *_helper = sub {
       my ($node) = @_;
       push @rv, $node->text;
       for my $child ($node->children) {
          _helper($child);
       }
   };

   _helper($node);
   return @rv;
}

更接近您想要的东西称为“动态范围变量”。它使用全局变量,但在调用子退出后恢复变量的值。

sub subroutine2 {
   our $x;
   print $x;
}

sub subroutine1 {
   local our $x = 'hello';
   subroutine2();
}

subroutine1();

如果我们知道您实际面临的问题,那么帮助您将更容易。但它要么涉及全局var或闭包。