[I ran into the issues that prompted this question and my previous question at the same time, but decided the two questions deserve to be separate.]
The docs describe using destructuring assignment with my
and our
variables, but don't mention whether it can be used with has
variables. But Raku is consistent enough that I decided to try, and it appears to work:
class C { has $.a; has $.b }
class D { has ($.a, $.b) }
C.new: :a<foo>; # OUTPUT: «C.new(a => "foo", b => Any)»
D.new: :a<foo>; # OUTPUT: «D.new(a => "foo", b => Any)»
However, this form seems to break attribute defaults:
class C { has $.a; has $.b = 42 }
class D { has ($.a, $.b = 42) }
C.new: :a<foo>; # OUTPUT: «C.new(a => "foo", b => 42)»
D.new: :a<foo>; # OUTPUT: «C.new(a => "foo", b => Any)»
Additionally, flipping the position of the default provides an error message that might provide some insight into what is going on (though not enough for me to understand if the above behavior is correct).
class D { has ($.a = 42, $.b) }
# OUTPUT:
===SORRY!=== Error while compiling:
Cannot put required parameter $.b after optional parameters
So, a few questions: is destructuring assignment even supposed to work with has
? If so, is the behavior with default values correct/is there a way to assign default values when using destucturing assignment?
(I really hope that destructuring assignment is supported with has
and can be made to work with default values; even though it might seem like a niche feature for someone using classes for true OO, it's very handy for someone writing more functional code who wants to use a class as a slightly-more-typesafe Hash with fixed keys. Being able to write things like class User { has (Str $.first-name, Str $.last-name, Int $.age) }
is very helpful for that sort of code)