2016-08-07 21 views
6

Bir rolün bir özniteliği varsayılanı sağlamak için geçersiz kılmak mümkün müdür?Bir Rolün Özniteliğini Geçersiz Kılma

role A { 
    has $.a; 
} 
class B does A { 
    has $.a = "default"; 
} 
my $b = B.new; 

Bu derleme hatası ile sonuçlanır: R yılında yöntemler $!a anlamlara gelebilir

===SORRY!=== Error while compiling: 
Attribute '$!a' already exists in the class 'B', but a role also wishes to compose it 

cevap

5

yana adlandırılan özellik belirsizlik olacaktır.

Devralınan/mixedin özniteliklerini başlatmak için alt yöntem BILDIR kullanın.

role R { has $.a }; 
class C does R { 
    submethod BUILD { $!a = "default" } 
}; 
my $c = C.new; 
dd $c; 
# OUTPUT«C $c = C.new(a => "default")␤» 

Usecase'inize bağlı olarak, varsayılanı bir role parametresi aracılığıyla ayarlamak daha iyi olabilir.

role R[$d] { has $.a = $d }; 
class C does R["default"] { }; 
my $c = C.new; 
dd $c; 
# OUTPUT«C $c = C.new(a => "default")␤» 
+2

"R'deki yöntemler $ 'a başvurabileceğinden, a atıfta bulunulması gereken belirsizlikler olabilir." Bu, OP'nin yaklaşımının neden işe yaramayacağı veya ilk çözümünüzde bile ortaya çıkabilecek ve ikinci çözümünüzle (parametrik bir rolün kullanımı) çözülen bir sorun hakkında neden konuşuluyor? – raiph

1

Hayır, bir öznitelik redeclare mümkün değildir - ama sen BUILD sınıfın submethod kullanarak başlatabilir:

role A { 
    has $.a; 
} 

class B does A { 
    submethod BUILD(:$!a = 'default') {} 
} 

Not Bundan sanki BUILD bünyesinde değerini ayarlarsanız yerine

class B does A { 
    submethod BUILD { $!a = 'default' } 
} 

aracılığıyla kendi imzasının kullanıcı B.new(a => 42) kullanarak da adlandırılmış başlatıcısı sağlayarak varsayılan üzerine yazmak mümkün olmaz.

role A[$d] { 
    has $.a = $d; 
} 

class B does A['default'] {} 
:

varsayılan ayarını (varsayılan değer Rolün arayüzünün bir parçası olarak görülebilir yani) çok şey bekliyoruz şey ise özellikle yararlıdır başka, daha şık bir yaklaşım bunu bir parametreyi yapıyor