Perl语法用法,使用strict和local

rua*_*hao 1 perl

我有Perl local语法的问题.

代码如下:

#!/usr/bin/perl -w

&outer;

sub outer {
    local $lvar = 'local';
    &inner;
}

sub inner {
    print "lvar: $lvar\n";
}
Run Code Online (Sandbox Code Playgroud)

如果我运行代码,它输出:

lvar: local
Run Code Online (Sandbox Code Playgroud)

但如果代码修改如下:

#!/usr/bin/perl -w
use strict;

&outer;

sub outer {
    local $lvar = 'local';
    &inner;
}

sub inner {
    print "lvar: $lvar\n";
}
Run Code Online (Sandbox Code Playgroud)

然后,出现错误:

Global symbol "$lvar" requires explicit package name at ./test.pl line 7.
Global symbol "$lvar" requires explicit package name at ./test.pl line 12.
Execution of ./test.pl aborted due to compilation errors.
Run Code Online (Sandbox Code Playgroud)

我在这里很困惑.我想最小化范围$lvar,我也想使用strict指令.但似乎他们无法共存.

use strict;local共存?或者,我要陈述our $lvar一下吗?

Bor*_*din 8

local几乎不是你想要的.使用my,声明一个在封闭块的整个(其余部分)可见的变量.

目前还不清楚你想要做什么,但如果你需要在两个子程序之间共享变量并保护它不被其他地方访问,那么你可以写这样的东西.请注意,这是一个闭包,并且$lvar在调用任一子例程时,值都是持久的.

请注意,不应使用&subname语法调用子例程.自从Perl 5于1994年推出以来,这是错误的.请subname()改用.

use strict;
use warnings;

outer();

{
  my $lvar;

  sub outer {
      $lvar = 'local';
      inner();
  }

  sub inner {
      print "lvar: $lvar\n";
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @ruanhao:因为`&subroutine`**a)**会覆盖任何原型,可能在子程序定义中,**b)**将当前的`@ _`值作为参数列表传递给你希望它传递一个空列表,因此您不得不在任何参数周围使用括号.它也很难看,正如我所说的那样,近二十年过时了.如果你想将用户定义的子程序与内置运算符分开,那么你可以在它们之前添加`my_`,但是我从未见过它已经完成或已经完成的情况. (4认同)

Chr*_*oms 7

使用my声明词法变量.这个改写怎么样?

#!/usr/bin/perl
use strict;
use warnings;
outer();

sub outer {
    my $lvar = 'local';
    inner($lvar);
}

sub inner {
    my $lvar = shift;
    print "lvar: $lvar\n";
}
Run Code Online (Sandbox Code Playgroud)

资源:

应对范围界定(包括my对比的讨论local).

另一个很好的资源是Modern Perl这本书.只需搜索"词汇".


ike*_*ami 5

local不声明/创建变量 - 它只是创建现有变量的自动恢复备份 - 所以你仍然需要声明$lvar.由于local只适用于包变量[1],这是人们需要使用our而不是使用的罕见情况之一my.

outter();
sub outter {
    local our $lvar = 'local';
    inner();
}
sub inner {
    our $lvar;
    print "lvar: $lvar\n";
}
Run Code Online (Sandbox Code Playgroud)

您还可以将变量声明为"全局".

our $lvar;
outter();
sub outter {
    local $lvar = 'local';
    inner();
}
sub inner {
    print "lvar: $lvar\n";
}
Run Code Online (Sandbox Code Playgroud)

或者只为两个潜艇一次.

outter();
{
   our $lvar;
   sub outter {
       local $lvar = 'local';
       inner();
   }
   sub inner {
       print "lvar: $lvar\n";
   }
}
Run Code Online (Sandbox Code Playgroud)

但实际上,local当您被迫使用包变量时,您应该只想使用它.在创建自己的变量时,您需要使用my.

outter();
{
   my $lvar;
   sub outter {
       $lvar = 'local';
       inner();
   }
   sub inner {
       print "lvar: $lvar\n";
   }
}
Run Code Online (Sandbox Code Playgroud)
  1. 它还适用于词法和包变量的哈希元素和数组元素.