I should have started off with what Liz wrote. Switch BUILD
to TWEAK
. Then the default BUILD
will do its thing and your socket attributes will get correctly initialized.
The next problem is &on-close
. See Lizmat's answer to Constructors in subclases showing how to deal with that if you can modify the superclass (Tap
in this case) or Jonathan's authoritative answer to Inheriting private attributes in Perl 6 (which is about any access whatsoever to another class's attributes) showing you're out of luck if you can't modify the superclass.
Note that the above two issues aren't really about "private attributes" in a class making "public attributes" undefined. Nor are types relevant.
All attributes are technically private. The private/public distinction is about whether there's a public accessor for a private attribute.
Your custom BUILD
is only initializing $!VMIO
, the one that doesn't have a public accessor. You have neglected to initialize $!socket-host
and $!socket-port
, the attributes that do have public accessors (due to use of the public accessor twigil .
when declaring them).
You presumably wrote a custom BUILD
because the default BUILD
only initializes attributes with public accessors. But if you do that you are taking on full responsibility for object construction and you must initialize all attributes that you want initialized.
It's better to write a TWEAK
. Then you can just deal with the attributes without public accessors. A TWEAK
just adds further initialization to the BUILD
, which for the default BUILD
is just initialization of the attributes with public accessors.