2009-08-04 63 views
1

我正在擴展一個模塊,我想了解一些有關良好實踐的提示。特別命名空間衝突:他們究竟是什麼以及如何避免它們。我應該如何訪問Perl子類中的實例數據?

擴展時,我不應該訪問SUPER類中的變量,只能通過訪問器或對象方法更改其狀態?如果沒有(或有限)訪問者,該怎麼辦?我「允許」直接訪問這些對象變量嗎?

乾杯!

回答

6

最好只通過訪問者訪問事物,因爲這可以防止超類實現中的變化影響子類。你應該遠離任何以底線開始的東西。這些東西對班上是私人的。儘量遠離任何沒有記錄的東西。依靠這些東西會讓你陷入麻煩。另外,考慮使用has-a與is-a的關係。

讓我們來想象一個小部件類。這個類有名稱和價格的成員(注意,這一切都不是特別好代碼,我剛纔扔的版本出來思考了一個例子的緣故):

package Widget; 

use strict; 
use warnings; 

sub new { 
    my $class = shift; 
    my %args = @_; 

    return bless { 
     price => $args{price} || 0, 
     name => $args{name} || "unkown", 
    }, $class; 
} 

sub price { shift->{price} } 
sub name { shift->{name} } 

1; 

你決定子類控件加配重塊:

package Widget::WithWeight; 

use strict; 
use warnings; 

use base 'Widget'; 

sub new { 
    my $class = shift; 
    my %args = @_; 
    my $self = $class->SUPER::new(%args); 
    $self->{weight} = $args{weight} || 0; 
    return bless $self, $class; 
} 

sub weight { shift->{weight} } 

sub price_per_pound { 
    my $self = shift; 
    return $self->{price}/$self->{weight}; 
} 

1; 

現在想象一下,第一個模塊的作者改變他/她對如何存儲的價格頭腦。或許正是存儲爲一個浮點數和作者意識到,把它作爲便士的整數會更好:

package Widget; 

use strict; 
use warnings; 

sub new { 
    my $class = shift; 
    my %args = @_; 

    if ($args{price}) {   
     $args{price} =~ s/[.]//; 
    } 

    return bless { 
     price => $args{price} || "000", 
     name => $args{name} || "unkown", 
    }, $class; 
} 

sub price { 
    my $self = shift; 
    my $price = $self->{price}; 
    substr($price, -2, 0) = "."; 
    return $price; 
} 

sub name { shift->{name} } 

1; 

突然,你的測試將啓動失敗,但如果你已經使用了price訪問,而不是,你會被這種改變所隔離。

+0

我沒有使用_foobar方法,但是,我直接訪問一些變量的內部表示,例如: 現實生活中的值存儲爲散列裁判是這樣的: $自= { 「財產」 = > {objnum => NUM,type => TYPE,value => VALUE}, } 我應該*不*直接通過$ self訪問'property',如$ self - > {property}?我應該只訪問它,如果它有一個get_property()訪問器? 在我的安裝腳本中'需要'SUPER類模塊的一個特定版本是一個白癡的事情嗎? – 2009-08-04 14:01:20

+0

如果它們沒有存儲在帶有下劃線的散列(例如`$ self - > {_ property}`)中,那麼它們是公平的遊戲,但是訪問方法是更安全的方法(保護您免受實施更改)。 – 2009-08-04 14:10:36

1

如果您從兩個模塊繼承爲一個模塊並且它們都提供(導出)相同的子項,則可能發生名稱空間衝突。

我建議你看看Moose,它是Perl的一個擴展,它爲你提供了類和角色。如果您使用角色,則可以避免許多衝突。請參見http://www.iinteractive.com/moose/

Moose還爲類變量生成自動訪問器,使得從繼承類訪問它們更安全。

相關問題