Override Role Attribute

Is it possible to override the role attribute for the default provision?

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

This results in a compilation error:

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

Since methods in R can reference $!a , there will be ambiguity about what the attribute refers to.

Use the BUILD subtopics to initialize the inherited / mixedin attributes.

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

Depending on your account, you might be better off setting a default value using the role parameter.

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

No, it is not possible to override an attribute, but you can initialize it using the subtext of the BUILD class:

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

Note that if you just set the value in the body of the BUILD instead of your signature via

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

the user cannot overwrite the default value by providing a named initializer through B.new(a => 42) .

Another, more elegant approach, which is especially useful when installing by default, is that you expect to do a lot (that is, the default value can be considered as part of the role interface) makes it a parameter:

 role A[$d] { has $.a = $d; } class B does A['default'] {} 
+1
source

All Articles