http://qs321.pair.com?node_id=11131790


in reply to [Raku] Assigning defaults to attributes that are fixed length lists (and other confusions)

If in your first attempt (with unless @!items) you instead use: say "Items: " ~ $hamper.items.perl; you will get

Name: Christmas Basket Items: Array.new(:shape(3,), [Any, Any, Any])

The code has @.items[3] is rw; creates a positional attribute which contains a fixed-length array with 3 elements. Thus, the array is truthy and the unless is not triggered.

When you change to @!items := ('Mince Pie', 'White Wine', 'Stinky Cheese', 'Sardines', 'Dogfood'); you replace the fixed-kength array with a new List. Since @!items is rw that is allowed -- you aren't modifying the fixed length array, you are replacing it. Since the [3] describes the array, not the attribute, this is all fine -- to raku, though not perhaps to you :).

There may be a way to do this using has, but at some point it is reasonable to write your own accessor:

class Hamper { has $.name = 'Christmas Basket'; has Str @!items; method TWEAK(){ self.items = 'Mince Pie', 'White Wine', 'Stinky Cheese' unless + @!items; } method items() is rw { return-rw Proxy.new: FETCH => sub ($) { return @!items }, STORE => sub ($, @items) { die "Wrong length" unless @items.elems == 3; @!items = @items; }; } } my $hamper = Hamper.new; # $hamper.items = 'Mince Pie', 'White Wine', 'Stinky Cheese', 'Dogfood +'; say "Name: " ~ $hamper.name; say "Items: " ~ $hamper.items;

Good Day,
    Dean