簡化過的問題如下:
#!/usr/bin/perl看起來很簡單的 code 卻暗藏玄機,居然 return 0; why??? 我左看右看,才想到可能是 exists 的問題。perldoc 的 exists 是這樣寫的:
use strict;
sub retundef {
#something wrong
return undef;
}
my $ret = &retundef();
if(exists $ret->{dummy}) {
print "gasp!?\n";
}
exit 1 unless $ret;
if(@{$ret->{list}}) {
local $, = ", ";
print @{$ret->{list}};
}
exit 0;
Although the mostly deeply nested array or hash will not spring into existence just because its existence was tested, any intervening ones will. .... This happens anywhere the arrow operator is used...原來在 $ret->{dummy} 以後, $ret 就自動變成 hash reference 了,雖然 $ret->{dummy} 還是不存在,但是卻改變了 $ret。
------------
不得不說,喜歡 C 不是沒有原因的... perl 寫起來方便(光是 hash table 就大勝) 但是對於一些 reference,包括 GC 的處理上的確不太透明;看來我要學得東西還很多...
4 則留言:
應用 defined()
defined 應該也一樣吧, 主要是在 ->{dummy} 的時候, $ret 變成 hashref 了
給你參考這個 https://gist.github.com/662096
咦對~
不過因為 defined 和 exists 基本上就是要對 hashref 操作的,所以也才會自動轉型。
但是 其實應該很少人這樣寫
如果要對 var 要做 exists 或 defined ,那就要假定 var 是 hashref 囉 ^^
所以在 exit 1 unless $ret; 的部份
通常會寫成 exit 1 unless %$ret;
然後在傳 $ret 之前建議一開始就指定 $ret ||= {}; 。
張貼留言