我正在擴展一個模塊,我想了解一些有關良好實踐的提示。特別命名空間衝突:他們究竟是什麼以及如何避免它們。我應該如何訪問Perl子類中的實例數據?
擴展時,我不應該訪問SUPER類中的變量,只能通過訪問器或對象方法更改其狀態?如果沒有(或有限)訪問者,該怎麼辦?我「允許」直接訪問這些對象變量嗎?
乾杯!
我正在擴展一個模塊,我想了解一些有關良好實踐的提示。特別命名空間衝突:他們究竟是什麼以及如何避免它們。我應該如何訪問Perl子類中的實例數據?
擴展時,我不應該訪問SUPER類中的變量,只能通過訪問器或對象方法更改其狀態?如果沒有(或有限)訪問者,該怎麼辦?我「允許」直接訪問這些對象變量嗎?
乾杯!
最好只通過訪問者訪問事物,因爲這可以防止超類實現中的變化影響子類。你應該遠離任何以底線開始的東西。這些東西對班上是私人的。儘量遠離任何沒有記錄的東西。依靠這些東西會讓你陷入麻煩。另外,考慮使用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
訪問,而不是,你會被這種改變所隔離。
如果您從兩個模塊繼承爲一個模塊並且它們都提供(導出)相同的子項,則可能發生名稱空間衝突。
我建議你看看Moose,它是Perl的一個擴展,它爲你提供了類和角色。如果您使用角色,則可以避免許多衝突。請參見http://www.iinteractive.com/moose/
Moose還爲類變量生成自動訪問器,使得從繼承類訪問它們更安全。
我沒有使用_foobar方法,但是,我直接訪問一些變量的內部表示,例如: 現實生活中的值存儲爲散列裁判是這樣的: $自= { 「財產」 = > {objnum => NUM,type => TYPE,value => VALUE}, } 我應該*不*直接通過$ self訪問'property',如$ self - > {property}?我應該只訪問它,如果它有一個get_property()訪問器? 在我的安裝腳本中'需要'SUPER類模塊的一個特定版本是一個白癡的事情嗎? – 2009-08-04 14:01:20
如果它們沒有存儲在帶有下劃線的散列(例如`$ self - > {_ property}`)中,那麼它們是公平的遊戲,但是訪問方法是更安全的方法(保護您免受實施更改)。 – 2009-08-04 14:10:36