2010-08-26 47 views
6

我與使用以下語法得到警告「哈希分配的元素奇數」 -警告 - 在Perl

my %data_variables = ("Sno." => (5,0), 
       "ID" => (20,1), 
       "DBA" => (50,2), 
       "Address" => (80,3), 
       "Certificate" => (170,4), 
      ); 

但我不明白,在使用類似的語法類似的警告。

my %patterns = ("ID" => ("(A[0-9]{6}?)"), 
       "Address" => (">([^<]*<br[^>]+>[^<]*)<br[^>]+>Phone"), 
       "Phone" => ("Phone: ([^<]*)<"), 
       "Certificate" => ("(Certificate [^\r\n]*)"), 
       "DBA" => ("<br[^>]+>DBA: ([^<]*)<br[^>]+>"), 
      ); 
+0

什麼也看http://stackoverflow.com/questions/2914183/how-do -i-interact-with-a-perl-object-that-has-a-hash-attribute – daxim 2010-08-26 14:09:11

+0

Perl的列表展平再次發生。列表展平具有有益的效果,但對於那些不習慣使用它的人來說也經常令人困惑。一個好處的例子是不需要特殊的應用函數(http://en.wikipedia.org/wiki/Apply),你可以建立一個函數參數的數據結構並簡單地使用它。 – daotoad 2010-08-28 06:14:20

回答

12

你需要改變你的括號方括號:

my %data_variables = (
    "Sno."  => [5,0], 
    "ID"   => [20,1], 
    "DBA"   => [50,2], 
    "Address"  => [80,3], 
    "Certificate" => [170,4], 
); 

哈希值必須是標量的值,因此您的號碼清單需要被存儲爲數組引用(因此方括號中)。

在你的第二個例子中,括號是多餘的,只是混淆了這個問題。每組圓括號只包含一個標量值(一個字符串),每個值都成爲一個散列值。

+5

只是一個狡辯(澄清):哈希值*是*標量 - 並將在每個可能的哈希構造函數中標量。如果你想要一個鍵來引用一個* structure *,你必須指定這個結構。如果你傳遞一個列表而不是一個arrayref,Perl會很樂意將這個列表分割成交替的鍵和值。問題是它構造了你不想要的散列。 ' 「斯諾」。 => 5,'0'=>'ID','20'=> 1,...' – Axeman 2010-08-26 13:35:48

+0

@Axeman右鍵 - 好的。 – FMc 2010-08-26 13:47:47

10

區別在於「...」是一個字符串(單個標量)而(5, 0)是兩個標量的列表。所以在第一個片段,你實際上這樣做:

my %data_variables = ("Sno.", 5, 0, "ID", 20, 1, "Address", 80, 3, "Certificate", 170, 4); 

由於哈希值是隻是有偶數個元素的列表,這將在元素的個數爲偶數的工作,但會失敗,如果它是奇象在你的例子中。

如果要將數組作爲值存儲在散列中,請改爲使用[5, 0]

2

你試圖把一個列表放在哈希元素中,並將它看作更多的鍵/值對。你真的想要做的就是把陣列裁判,像

my %data_variables = ("Sno." => [5,0], 
       "ID" => [20,1], 
       "DBA" => [50,2], 
       "Address" => [80,3], 
       "Certificate" => [170,4], 
      ); 

你可以參考數組元素

my $foo = $data_variables{"Sno"}->[0]; 
    my $bar = $data_variables{"Address"}->[1];