2016-08-07 6 views
6

역할의 속성을 재정의하여 기본값을 제공 할 수 있습니까?역할의 속성 무시

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

이 컴파일 오류가 발생합니다 R의 방법 $!a 참조 할 수 있습니다

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

답변

5

때문에라고 어떤 속성 모호함이있을 것입니다.

submethod BUILD를 사용하여 계승/혼합 속성을 초기화합니다.

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")␤» 

사용 여부에 따라 역할 매개 변수를 통해 기본값을 설정하는 것이 좋습니다.

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의 메소드가 $! a를 참조 할 수 있으므로 어떤 속성이 참조되는지 모호하게됩니다." OP의 접근 방식이 작동하지 않는 이유 또는 첫 번째 솔루션으로도 발생할 수있는 문제와 두 번째 솔루션 (매개 변수 역할 사용)으로 해결되는 이유에 대해 이야기하고 있습니까? – raiph

1

아니, 그것은 속성을 재 선언 할 수 없습니다 -하지만 당신은 BUILD 클래스의 하위 방법 사용하여 초기화 할 수 있습니다 :

role A { 
    has $.a; 
} 

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

주 당신은 BUILD의 신체 내에서 값을 설정하는 경우 대신

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

를 통해 그 서명의 사용자는 B.new(a => 42)를 통해 명명 된 초기화를 제공하여 기본값을 덮어 쓸 수 없을 것입니다.

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

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

기본값을 설정하는 것은 당신이 (기본 값은 역할의 인터페이스의 한 부분으로 간주 될 수있다 즉)을 많이 할 것으로 예상 무언가가있는 경우에 특히 유용합니다 또 다른, 더 우아한 방법은 그것을 매개 변수를하고있다