Like most things in Perl5, there are many ways to create a class that supports custom type coercions for its attributes. Here's a simple one, from an array reference to a hash:
#!/usr/bin/env perl
package Local::Class {
use Moo;
use Types::Standard qw( HashRef ArrayRef );
has set => (
is => 'ro',
coerce => 1,
isa => HashRef->plus_coercions(
ArrayRef, sub { return { map { $_ => 1} @{$_[0]} } },
),
);
}
my $o = Local::Class->new({ set => [qw( a b b c )] });
# $o->set now holds { a => 1, b => 1, c => 1}
I've been trying to port something like this to Perl6, where it seems like what I need is a way to coerce an Array
to a SetHash
. So far, the only way I've been able to do that is like this:
#!/usr/bin/env perl6
class Local::Class {
has %.set;
## Wanted to have
# has %.set is SetHash;
## but it dies with "Cannot modify an immutable SetHash"
submethod TWEAK (:$set) {
self.set = $set.SetHash;
}
}
my $o = Local::Class.new( set => [< a b b c >] );
# $o.set now holds {:a, :b, :c}
But this doesn't seem to me to be the right way to do it, at the very least for the tiny detail that passing an odd-numbered list to the constructor makes the script die.
So, how is this done in Perl6? What are the recommended ways (because I'm sure there's more than one) to implement custom type coercions for class attributes?