I was wondering how to mix in an abstract role into a variable in runtime. Here's what I came up with
role jsonable {
method to-json( ) { ... }
}
class Bare-Word {
has $.word;
method new ( Str $word ) {
return self.bless( $word );
}
}
my $that-word = Bare-Word.new( "Hola" ) but role jsonable { method to-json() { return "['$!word']"; } };
However, this throws an (perfectly reasonable) error:
$ perl6 role-fails.p6
===SORRY!=== Error while compiling /home/jmerelo/Code/perl6/dev.to-code/perl6/role-fails.p6
Attribute $!word not declared in role jsonable
at /home/jmerelo/Code/perl6/dev.to-code/perl6/role-fails.p6:14
------> hod to-json() { return "['$!word']"; } }⏏;
expecting any of:
horizontal whitespace
postfix
statement end
statement modifier
statement modifier loop
$!word
belongs to the class, so it is not available as such in the mixin declaration. However, but is simply a function call so the declared variable should be available inside, right? What would be the right syntax to access it?
The right syntax would be $.word
, which is basically short for self.word
, so it uses the public access method.
But I think there are some typos and some misconceptions here. The typo (I think) is that .bless
only takes named parameters, so instead of $word
, it should be :$word
(turning a positional to word => $word
). Also, a role that defines but not implements a method, and then use the same name to implement a role with that name, doesn't make sense. And I'm surprised it doesn't generate an error. So get rid of it for now. This is my "solution":
class Bare-Word {
has $.word;
method new ( Str $word ) {
return self.bless( :$word ); # note, .bless only takes nameds
}
}
my $that-word = Bare-Word.new( "Hola" ) but role jsonable {
method to-json() {
return "['$.word']"; # note, $.word instead of $!word
}
}
dd $that-word; # Bare-Word+{jsonable}.new(word => "Hola")
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With