-
- exist EXPR
如果所声明的散列键字或者数组索引在它的散列或者数组中存在,那么这个函数返回真值。它不在乎对应的数值是真还是假,或者该值是否定义。
print "True\n" if $hash{$key}; print "Defined\n" if defined $hash{$key}; print "Exists\n" if exists $hash{$key}; print "True\n" if $array[$index]; print "Defined\n" if defined $array[$index]; print "Exists\n" if exists $array[$index];
一个元素只有定义后才为真,并且只有存在才能被定义,但反过来却不一定是真的。
EXPR 可以任意复杂,前提是它的最后的操作是一个散列键字或者索引查找:
if (exists $hash{A}{B}{$key} ) { ... }
尽管最后一个元素不会只是因为它的存在性已经经过测试而存在,中间的元素却会。因此 $$hash{"A} 和 $hash{"A"}->{"B} 都将真正存在。这个功能不是 exists 函数本身的;它发生在任何使用了箭头操作符的地方(明确地或隐含地):
undef $ref; if (exists $ref->{"Some key"}) { } print $ref; # 打印 HASH(0x80d3d5c)
即使 "Some key" 元素没有突然存在,前面未定义的 $ref 变量也会突然变成持有一个匿名散列的变量。这是一个那种第一眼——甚至第二眼看上去都不是左值环境条件下的自动激活的一个有趣的例子。这种行为在将来的版本里可能会被修补。作为绕开的一种方法,你可以嵌套你的调用:
if ($ref and exists $ref->[$x] and exists $ref->[$x][$y] and exists $ref->[$x][$y] and exists $ref->[$x][$y]{$key} and exists $ref->[$x][$y]{$key}[2] ) { ... }
如果 EXPR 是子过程的名字,如果该子过程已经定义,那么exists 函数将返回真,即使该子过程还没有定义也如此。下面的程序将打印 “Exists”:
sub flub; print "Exists\n" if exists &flub; print "Defined\n" if defined &flub;
在一个子过程名字上使用 exists 可以用于 AUTOLOAD 子过程,这个子过程可能需要知道某个包是否需要某个子过程的定义。该包可以通过声明一个想 flub 那样的 sub 存根来实现这个目的。