2017-05-12 13 views
1

我目前正在創建Perl中的類,它看起來像這樣:在構造函數輸入數組 - Perl的

sub new{ 
    $class = shift; 
    $self = { 
    #Member Variables 
    server => shift, 
    type => shift, 
    domains => shift 
    }; 
    bless $self, $class; 
    return $self; 
} 

我想域是多變量數組。如何在使用班次時將數組與正常變量區分開來?我想輸入數組是這樣的:

my $var = new class("server",1,(1,2,3)); 
my $var = new class("server",1,[1,2,3]); 

試圖通過數組迭代時做無論這些工作:

for $i ($self->{domains}){ 
    print "$i\n"; 
} 
+1

所有的方式,你***必須始終***'使用strict'和'使用警告「所有」 '在每個Perl源文件的頂部,並使用'my'聲明每個變量。 – Borodin

回答

5

參數傳遞給一個函數作爲標量的列表,你的第一次調用只是

my $var = new class("server",1,1,2,3); 

的哈希值需要是一個標量,所以你需要一個匿名陣中還有

domains => [ LIST ]; 

因此,無論

  • shift關閉所有單選項,你做什麼,然後剩下的複製到數組引用

    domains => [ @_ ]; 
    
  • 或傳遞一個數組引用,這是一個標量,就像你的第二個調用和它分配

    domains => shift; 
    

在這兩種情況下,$self->{domains}將會是一個arrayref。

在另一方面,可以考慮很好分配參數第一

sub new { 
    my ($class, $server, $type, @domains) = @_; 
    # ... 
    my $self = { 
     # ... 
     domains => \@domains 
    }; 
    return bless $self, $class; 
} 

對於第一次調用,或

sub new { 
    my ($class, $server, $type, $rdomains) = @_; 
    my $self = { 
     # ... 
     domains => $rdomains 
    }; 
    return bless $self, $class; 
} 

爲第二個。由於bless返回其第一個參數,我們可以直接return(爲簡潔起見)。

最後,您使用indirect object notation來調用構造函數。總之,不要 - 使用

my $object = ClassName->new(ARGS); 

參見上面的鏈接,官方聲明和this post


總是warnings運行,因爲這節省了很多麻煩。我也強烈建議始終使用strict,因爲它採用了面向對象的Perl尤其在促進良好做法

# At the beginning of every program 
use warnings 'all'; 
use strict; 
+0

嘿zdim,我還需要在設置'my $ self = {...}'後包含'bless $ self,$ class;'和'return $ self;'? – user081608

+0

@ user081608是的,無論如何。設置'$ self'只是在程序中填充hashref。 ''self'是'$ self'的對象,在'$ self'這行之後''self'「知道」它屬於哪個類,你可以調用它的方法等等。返回'這對各種用途都很重要。我已經補充說,爲了完整,謝謝你的提問。 – zdim

3

如果你想作爲一個列表來指定域,您需要這樣做:

sub new { 
    $class = shift; 
    $self = { 
    server => shift, 
    type => shift, 
    domains => [ @_ ], 
    }; 
    bless $self, $class; 
    return $self; 
} 

這是因爲散列不能有非標量鍵或值。

無論哪種方式,你正在經歷域迭代時,必須取消引用該數組引用:

for my $domain (@{ $self->{domains} }){ 
    print "$domain\n"; 
}