2015-07-10 223 views
2

所以,我有包含數組的對象:通過陣列循環

package MyObject; 

sub new { 
    my($type) = @_; 
    my $self->{Params}{Status}{Packages} = []; 
} 

我有一個添加該附加新的包的子到這樣的「程序包」陣列:

sub add_package { 
    my($self, $package_obj) = @_; 

    push $self->{Params}{Status}{Packages}, $package; 
} 

現在,當我去找我陣列中的所有包時,我遇到了問題。每當我嘗試並拉出這樣的包裝:

foreach my $package($self->{Params}{Status}{Packages}) { 
    # do something with $package. 
} 

這隻能循環一次。現在,從我瞭解的哈希實際存儲的指針數組所以我嘗試做的事:

foreach my $package(@$self->{Params}{Status}{Packages}) { 
    # do something with $package. 
} 

但後來有一個錯誤,指出$自我不是一個數組。我也注意到,當我做:

scalar $self->{Params}{Status}{Packages}; 

它返回:

@ARRAY(0xSome Address); 

我缺少什麼?我怎樣才能使用foreach循環來通過我的數組?

回答

3

在這種情況下,你需要用它所有的數組取消引用塊@{}這樣的perl知道你要提領這部分...

for my $package (@{ $self->{Params}{Status}{Packages} }){ 
    print "$package\n"; 
} 

而且,只是爲了保持一致,我喜歡解壓時,或插入到總是DEREF與塊陣列:

push @{ $self->{Params}{Status}{Packages} }, $package; 

UPDATE:作爲5.24.0+,autoderef(使用keys()values()each()與參考)將幾乎certa將被刪除,並替換爲後綴引用。但是,使用@{}%{}將繼續得到支持,並向後兼容,因此我建議您始終使用它們。

4

$self->{Params}{Status}{Packages}是一個reference數組,用Perl的術語。當你有一些東西的時候,把正確的字符放在它的前面dereference it。如果引用不僅僅是前面可能帶有一些標記的名稱,則需要用括號包圍它。這是優先級的問題:@$self->{Params}{Status}{Packages}被解析爲(@$self)->{Params}{Status}{Packages},但你需要

@{$self->{Params}{Status}{Packages}} 

即通過表達$self->{Params}{Status}{Packages}所引用的數組。

1

在我看來,要做到這一點最明顯的方法是提取數組引用到一個臨時標量,這使得訪問數組非常簡單

my $packages = $self->{Params}{Status}{Packages}; 
for my $package (@$packages) { 
    # do something with $package. 
} 

另外,如果你有use strictuse warnings啓用爲你應該,你add_package子程序將產生消息

push on reference is experimental 

這是不是你可以放心地忽略。實驗性功能可能會改變它們的行爲或在更高版本的Perl中完全消失,並且在生產代碼中使用它們是不明智的。你可以用類似的方法修復你的子程序,像這樣

sub add_package { 
    my ($self, $package_obj) = @_; 

    my $packages = $self->{Params}{Status}{Packages}; 
    push @$packages, $package; 
}