Meta-programming capabilities using FALLBACK

Being a long time Ruby user and Lisp dabbler, Rakudo Perl 6 meta-programming capabilities ranked high on my list of curiosities.

Meta-programming can be described as "writing code that writes code".  This includes code that can alter itself.

I was experimenting and discovered I could not add an attribute to a class at runtime:

class Foo does Metamodel::AttributeContainer {
  submethod BUILD(:$attr) {
    my $a = Attribute.new(:name($attr), :type(Str), :package(Foo));
    self.add_attribute(self, $a);
  }
}

my Foo $foo = Foo.new(:attr('bar'));
$foo.bar = 'baz';  # No such method 'bar' for invocant of type 'Foo'
say $foo.bar;


I found the attribute could be managed in a Hash and if I used return-rw inside FALLBACK I could even return a mutable l-value:

class Foo {
  has %.attrs;
  method FALLBACK(Str:D $name, *@rest) {
    return-rw %!attrs{$name};
  }
}

my $foo = Foo.new;
$foo.bar = 'baz';
say $foo.bar;


Thanks to Jonathan Worthington for the help:

https://stackoverflow.com/questions/57993203/how-to-add-a-class-attribute-dynamically

raku (17)