perl eval使用包
问题描述:
中声明的未初始化的值任何人都可以向我解释为什么在包中声明的变量不能被eval函数访问,除非它在sub中使用一次?
(perl的v5.16.3 MSWin32-64的多线程的ActiveState)perl eval使用包
套餐:
use strict;
use warnings;
package testPackage;
my $insertVar = "TEST";
sub testSub {
my $class = shift;
my $test = shift;
eval '$test="'.$test.'";';
return $test;
}
1;
计划:
use strict ;
use warnings ;
use testPackage ;
my $testVar = q[insertVar = ${insertVar}] ;
$testVar = testPackage->testSub($testVar) ;
print "$testVar\n" ;
结果来执行程序时:
使用的未初始化值$ insertVar在串联(。)或字符串中 at (eval 1)line 1. insertVar =
现在,如果我使用testSub中的变量(例如,打印出来):
use strict;
use warnings;
package testPackage;
my $insertVar = "TEST";
sub testSub {
my $class = shift;
my $test = shift;
print $insertVar . "\n";
eval '$test="'.$test.'";';
return $test;
}
1;
然后该程序运行完全一样我打算:
TEST
insertVar = TEST在一个文件中声明
答
my
变量(花括号外)当文件完成执行时(在require
和use
返回之前)超出范围。
$insertVar
只会在文件完成执行后才会继续存在,如果它被子捕获,并且只有捕获它的子文件才可见。
出于效率的原因,潜艇捕获了尽可能少的变量。如果子没有引用$insertVar
,它将不会捕获它。由于您的第一个testSub
未参考$insertVar
,因此它不捕获它。由于$insertVar
在您拨打testSub
时已超出范围,因此eval
不可用。您应该收到警告Variable "$insertVar" is not available
,但由于我未知的原因,它会针对您使用的特定代码发布。
你的第二个testSub
参考$insertVar
,所以testSub
捕获$insertVar
并保持它活着。即使$insertVar
在您拨打testSub
时已超出范围,但eval
可用,因为它已被该子捕获。
如果您使用our
声明变量,它们将是全局包变量,因此不会超出范围,它们将可用于eval
。
>perl -wE"use strict; use warnings; { my $x = 'abc'; sub foo { $x } } say foo()"
abc
>perl -wE"use strict; use warnings; { my $x = 'abc'; sub foo { eval '$x' } } say foo()"
Variable "$x" is not available at (eval 1) line 2.
Use of uninitialized value in say at -e line 1.
>perl -wE"use strict; use warnings; { our $x = 'abc'; sub foo { eval '$x' } } say foo()"
abc
为什么地球上你会''评估一个变量的赋值来设置自己? – TLP