任何人都可以向我解释为什么eval函数无法访问包中声明的变量,除非在sub中使用了一次?
(perl v5.16.3 MSWin32-x64-multi-thread ActiveState)
包装:
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 在(eval 1)第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
答案 0 :(得分:1)
my
变量在文件完成执行后(在require
和use
返回之前)超出范围。
$insertVar
只有在文件完成执行后才会继续存在,如果它被子捕获,它只会被捕获它的子视图看到。
出于效率原因,subs捕获尽可能少的变量。如果子没有引用$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
声明变量,它们将成为全局包变量,因此不会超出范围,并且{{1}可以使用它们}。
String[] dataFileds = new String[]{
MediaStore.MediaColumns.DATA,
OpenableColumns.DISPLAY_NAME,
OpenableColumns.SIZE};
Cursor cursor = context.getContentResolver().query(uri, dataFileds, null, null, null);
cursor.moveToFirst();
fileLocation = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA));
title = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
size = cursor.getInt(cursor.getColumnIndex(OpenableColumns.SIZE));
cursor.close();