How can I add an attribute to a class dynamically? I tried this but it's complaining about a missing method and I'm not sure why since I'm not trying to add a method.
use v6.d;
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;
There's no way to add an attribute to a class once it has been composed - that is, after its closing curly }
has been parsed. In general, declarative things done using the metamodel need to be done at compile time.
About the code that you have written in the question:
Metamodel::AttributeContainer
role won't help anything here; it's to be composed into a meta-class, which holds the metadata about attributes, rather than the class that has the attributes being declared.bar
not being found is because an attribute accessor - even a generated one - is just an ordinary method.It's hard to know what to suggest instead without knowing the problem you were trying to solve in the first place. Whatever it is, it can't be solved by trying to add attributes per-object. Perhaps consider either:
FALLBACK
method to resolve method calls into hash accesses for the valid keysIf 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