2015-06-02 70 views
2

當$ perlobj傾倒這個我目前有以下無法正確合併哈希

# $dog, $cat, $rat are all hash refs 

       my %rethash = ('success' => 'Your Cool'); 

       my %ref ={ 'dog' => $dog, 'cat' => $cat, 'mouse' => $rat, 
           'chicken' => '' }; 

       my $perlobj = (\%ref,\%rethash);  

是結果

$VAR1 = { 
     'success' => 'Your Cool' 
    }; 

然而,當警告使我得到以下信息

Useless use of reference constructor in void context at .. 

我意識到如何使用{}分配%ref存在一些可怕的錯誤,這段代碼有什麼問題?我似乎無法擺脫這種警告....

編輯: 好吧,我想我想通了,怎麼回事,

my $perlobj = (\%ref,\%rethash); 

這不會合並,但在$ perlobj成爲結果參考%rethash,在閱讀你的回答之後,這是顯而易見的。

+4

當你使用'()'創建'%ref'時使用'{}' – RobEarl

+1

你也希望'我的%perlobj =(%ref,%rethash);' – RobEarl

+1

可能的重複[如何在Perl中結合散列?](http://stackoverflow.com/questions/350018/how-can-i -combine-hashes-in-perl) – RobEarl

回答

5

RobEarl說的是正確的。我會給出一個解釋,並添加更多的東西。

您的變量名稱%ref以及您使用{}的事實意味着您需要在此處參考。

讓我們來看看我們在%ref中會有什麼價值。考慮這個例子。

use strict; use warnings; 
use Data::Printer; 
my %foo = { key => 'value' }; 
p %foo; 

,這將拋出發現了一個警告參考,甚至大小的名單上我的Perl 5.20.2的預期。輸出將是:

{ 
    HASH(0x7e33c0) undef 
} 

這是一個hashref爲關鍵和undef爲值的哈希。 HASH(0x07e33c0)是您在查看散列引用而不引用它時獲得的結果。 ({}是因爲Data :: Printer將散列轉換爲hashref)。

回到您的代碼,參考的正確印記是$。它是什麼樣的參考並不重要。引用總是一個標量(指向內存中存放散列/數組/東西的地方的指針)。

my $ref = { 
    dog  => $dog, 
    cat  => $cat, 
    mouse => $rat, 
    chicken => '', # maybe this should be undef? 
}; 

現在你已經有了與$dog$cat$rat值和一個空字符串hashref。

現在您正在分配一個名爲$perlobj的變量,這意味着它是一個對象。相反,您正在使用列表分配一個標量變量($使其成爲標量)。如果你這樣做,Perl只會將最右邊的值賦給變量。

my $foo = (1, 2, 3); # $foo will be 3 and there's a warning 

您正在分配兩個引用的列表。第一個被忽視,只有\$rethash被分配。這很有效,因爲方便,$perlobj是一個標量,引用也是標量。所以現在$perlobj%rethash的參考。這就是爲什麼你的Data :: Dumper輸出看起來像%rethash


我不確定你想要做什麼,所以我不能真正幫助你。我建議你閱讀一些東西。

  • perlreftut是非常有用的學習參考資料如何工作
  • 如果你想要做的面向對象編程,檢查出Moose
  • 這也可能是有用的,只是去得到一本書來學習一些關於基本Perl的。 學習Perl的由蘭德爾L. Schwartz和柯蒂斯坡起的Perl都爲
+0

感謝您的分解,我真的很感激它,我正在瀏覽一些舊的代碼並向模塊添加警告並發現此錯誤。 – ingueni

2

你正在服用的散列引用的列表,並將它們分配給一個標量

my $perlobj = (\%ref, \%rethash); # same as $perlobj = \%rethash 

非常好相反,你想參考一個哈希合併

my $perlobj = { %ref, %rethash };