2010-10-18 101 views
5

我有以下的(從錯誤理想化的)短Perl腳本:爲什麼我的哈希不是undef?

my %metadata = undef; 
if (defined %metadata) 
{ 
    print "defined"; 
} 

出於某種原因,該程序的輸出總是「定義」。因此,將哈希設置爲「未定義」會以某種方式使其定義。它被定義爲「未定義」嗎?

編輯:

這是一種理想化的情況下,企圖複製的問題。什麼我實際上做的更像是:

my %metadata = my_sub_function(); 
if (defined %metadata) 
{ 
    print "defined"; 
} 

凡my_sub_function的輸出可能是民主基金,()或填充亂碼,我只希望在最後的這些情況下打印「定義」。

編輯2:

順便說一句我發現

if (scalar(keys %metadata) 

行爲正確的(),但仍然不是民主基金。

+3

不'my_sub_function'做了'回undef'給我ndicate失敗或沒有數據?如果是這樣,它可能應該做一個簡單的'返回'而不是。這將被解釋爲標量上下文中的「undef」和列表上下文中的「()」(空列表)。 – 2010-10-18 13:13:23

回答

8

如果你的函數返回undef和民主基金被放置在聯合國民主基金是''哈希,自動字串的變化和你結束了:%metadata = ('' => undef)

如果你的函數需要返回要麼undef()或正確的散列,你需要分別測試這三種情況下,我建議:

my %metadata = my_sub_function(); 
if (!scalar keys %metadata) { 
    print "An empty list() was returned\n" 
} elsif (
    scalar keys %metadata == 1 and 
    exists $metadata{''} and 
    !defined $metadata{''} 
) { 
    print "undef or '' was returned\n"; 
} else { 
    print "A hash was hopefully returned\n"; 
} 

你可以用下面的my_sub_functions測試:

sub my_sub_function { return()     } # 1st case 
sub my_sub_function { return undef    } # 2nd case 
sub my_sub_function { return (a => 1, b => 2) } # 3rd case 
sub my_sub_function { return qw/not a hash/  } # unhandled case 

快樂黑客

+1

精彩;非常感謝! Perl總是讓我感到困難是多麼的容易,有些事情應該是簡單的:) – 2010-10-18 14:21:28

8

嘗試

my %metadata; 
undef %metadata; 
if (defined %metadata) 
{ 
    print "defined"; 
} 

我認爲它只是用「民主基金」的數據來填充哈希。

「使用警告」會說:

defined(%hash) is deprecated at t.pl line 6. 
    (Maybe you should just omit the defined()?) 
Odd number of elements in hash assignment at t.pl line 4. 
Use of uninitialized value in list assignment at t.pl line 4. 

民主基金,()或填充的哈希

如果你真的想要一個空的哈希和沒有哈希區分,更好使用散列引用(也可以使用較輕的來自子例程,不傳遞所有副本)。

+0

啊,有意思!我在日誌中沒有看到這個錯誤,並且它的代碼使用嚴格並使用警告。我也嘗試過沒有定義(%散列),雖然有相同的結果。 – 2010-10-18 10:57:05

+0

不幸的是,我並不負責直接從子函數返回的內容,所以我必須使用我提供的內容:) – 2010-10-18 11:00:44

+0

「不再使用定義在聚合(哈希和數組)上的方法。它用於報告是否曾經分配過該聚集的內存,這種行爲在未來的Perl版本中可能會消失,您應該使用簡單的大小測試「。所以,你現在的做法可能不太好。更好地與製作該子程序的人交談。 – Thilo 2010-10-18 11:06:37

1

試試這個

%metadata=("1"=>"one"); 
undef %metadata; 
if (%metadata) 
{ 
    print "defined"; 
} 

如果你看一下在perldoc -f defined的文檔,它說,檢查的方式這個不推薦使用。

Use of "defined" on aggregates (hashes and arrays) is deprecated. 
2

,如果你看到的defined的文檔,你會發現,

When defined used on a hash element, 
it tells you whether the value is defined, 
not whether the key exists in the hash. 

儘量簡單,if (%a_hash) { print "has hash members\n" }

注:undef是一個從未被初始化的變量的值(或者使用undef函數已被重置)。 The defined function returns true if the value of the expression is not undef.

相關問題