Posting a quick update to this as my new and improved understanding of attributes led me to a simple alternative which gave me what I wanted. I realised my main problem was the unless having the wrong effect. The phenomenon of overwriting the fixed length array with a longer one is really just a curiosity, since I don't think there's any practical situation when you'd define an N sized array, and then specify an N + 1 element array as the default. I think the unless issue can be resolved easily in either of 2 ways, depending on what effect is desired:

class Hamper { has $.name = 'Christmas Basket'; my Str @item_defaults[3] = 'Mince Pie', 'White Wine', 'Stinky Chee +se'; has Str @.items[3] is rw; method TWEAK(){ @!items[ $_ ] ||= @item_defaults[ $_ ] for @item_defaults.keys +; } } my $hamper = Hamper.new; say "Name: " ~ $hamper.name; say "Items: " ~ $hamper.items;

This simply has code in TWEAK assign defaults on a per element basis. This way you get defaults at the element level, so e.g. if you do this:

my $hamper = Hamper.new( items => ('Fish', 'Canoe') );

$hamper.items will end up with the user specified values Fish and Canoe as the first 2 elements, and Stinky Cheese as the 3rd. This might be good for some purposes, but in my case I wanted the defaults to be completely overwritten if the user specified any values for @!items at all. ie in the above example, asking for $hamper.items should return "uninitialized value" for the third item. Only if I don't try to set any items at all should I get the defaults. This seems quite straightforward to implement with grep:

method TWEAK(){ @!items = @item_defaults unless grep {$_}, @!items; }

This now achieves everything I hoped:

I think if you want exactly 3 (or however many) elements, then writing your own accessor is very likely your best option. (Or perhaps subclassing Array? Not really sure of the details there)

Anyway, I just thought I'd share in case it helps anyone else out...


In reply to Re^3: [Raku] Assigning defaults to attributes that are fixed length lists (and other confusions) by tomgracey
in thread [Raku] Assigning defaults to attributes that are fixed length lists (and other confusions) by tomgracey

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.