如何检查变量是否在perl中声明?

时间:2010-08-21 11:00:42

标签: perl

我在perl中使用use strict;,并使用以下语句。

unless(defined($x)){
      print "Not defined";
}

其中$ x未在任何地方声明。所以我希望它打印“Not defined”,但它会返回错误

Global symbol "$x" requires explicit package name at *********** in line 15.

8 个答案:

答案 0 :(得分:18)

strict pragma有三个部分:严格引用,严格变量和严格的subs。你遇到的那个是

  

严格的诉讼

     

如果您访问未通过ouruse vars声明,通过my本地化或未完全限定的变量,则会生成编译时错误。因为这是为了避免变量自杀问题和微妙的动态范围问题,仅仅local变量不够好。

因为它会生成编译时错误,所以非BEGIN代码甚至无法运行。您可以暂时允许块内的非严格变量,如

{
  no strict 'vars';
  print "Not defined!\n" unless defined $x;
}

但请注意,Perl的defined运算符会告诉您是否定义了值,而不是是否已声明变量。

告诉我们您的应用程序的更多信息,我们可以为您提供有关如何处理它的更好建议。

答案 1 :(得分:5)

除非声明变量,否则你甚至不能引用到变量中。当你问

defined( $x ) ?

编译器会抱怨:我不知道你问的是什么,我该如何判断它是什么?它没有该变量的参考点,因为您已经表明您不希望通过名称自动创建变量。

如果strict 'vars'未启用 - 默认情况下是use strict - 那么它会在包符号表中为'x'创建一个条目。

有趣的是,如果没有strict 'refs',也很容易检查变量是否在包符号表中。

defined( *{ __PACKAGE__ . '::x' }{SCALAR} )

由于无法自动创建词法(“我的变量”),因此也没有标准的方法来检查是否声明了词法。词汇变量存储在“pad”中。但是有一个模块PadWalker可以提供帮助。

为了检查当前级别,您可以获得打击垫的哈希值,然后检查它是否存在于当前打击垫中。你也可以通过堆栈循环(整数参数类似于caller)来查找最近的x所在的位置。

my $h = peek_my (0);
exists $h->{x};

答案 2 :(得分:5)

我认为你正在混合'已定义'和'已声明'的概念。

您要求'如何检查变量是否在perl中声明',但是您正在检查是否定义了变量。这是两个不同的概念。

在Perl中,如果你使用'use strict',你会自动检查任何变量未声明(使用我的本地我们的)。一旦声明了变量,就可以测试它是否已定义(已赋值)。

因此,在测试中,在测试defineness

之前,您缺少先前的声明
use strict;
my $x;  # you are missing this part
[...] | # code
# your test for define
print defined $x? "defined\n" : "not defined\n";

请注意,只有$ x的测试不符合您的目的:

my ($x,$y, $z);
$w;         # not declared (use strict will catch it and die)
$x = 0;     # declared and defined BUT if you make a logic test like 'if ($x) {}' then it will be FALSE, so don't confuse testing for **'$x'** and testing for **'defined $x'**
$y = undef; # declared but not defined
$z = 1;     # declared, defined, and logial test TRUE

最后,xenorraticide的答案对我来说似乎有问题:他建议',除非$ x'不正确用于测试,如果按照我之前的说法定义的话。他还建议'除非存在$ x',这对于测试标量是错误的。 'exists'测试仅适用于散列键(并且不推荐使用数组)。

希望这有帮助。

答案 3 :(得分:1)

 #
 print "Not defined" if !defined($x);

结果将是

未定义

 #
 use strict;
 print "Not defined" if !defined($x);

会在你的问题中产生错误。

查看:http://perldoc.perl.org/strict.html,其中描述了如何只导入所需的限制。 (但是使用严格的'vars'是非常好的主意:))

答案 4 :(得分:1)

通常这种代码不应该用于严肃的程序,但仍然为什么不仅仅是为了好玩:(假设使用严格)

print "Not defined\n" unless eval 'ref(\$x)';

答案 5 :(得分:0)

#!/usr/bin/perl -l

use strict;

# if string below commented out, prints 'lol' , if the string enabled, prints 'eeeeeeeee'
#my $lol = 'eeeeeeeeeee' ;
# no errors or warnings at any case, despite of 'strict'

our $lol = eval {$lol} || 'lol' ;

print $lol;

答案 6 :(得分:0)

我的解决方案是     #!/ usr / bin / perl -l <​​/ p>

use strict;

# if string below commented out, prints 'lol' , if the string enabled, prints 'eeeeeeeee'
#my $lol = 'eeeeeeeeeee' ;
# no errors or warnings at any case, despite of 'strict'

our $lol = eval {$lol} || 'lol' ;

print $lol;

答案 7 :(得分:-1)

您可以使用 unless,如下所示:

use 'strict';

my $var = 'defined';
unless (defined($var)) {
  print "not defined\n";
}

$var = undef;
unless (defined($var)) {
  print "not defined\n";
}

第一个 print 不会打印任何内容,第二个会因为 $var 已经生成 undef