Search code examples
perlcode-generationmoose

How to dynamically add an attribute if it not exists using perl AUTOLOAD and Moose::Meta::Class?


I'm trying to add to Class1 Resource1 attribute which value is test. However it's not working. What is wrong in my code?

package Class1;
use Moose;

sub AUTOLOAD {
    my $self = shift;
    our $AUTOLOAD;
    my $unknown_method_name = (split(/::/, $AUTOLOAD))[-1];
    require Class2; # generator class
    Class2->generate_one($self, $unknown_method_name);
}


package Class2;
use Moose;

sub generate_one {
  my ($self, $object, $p) = @_;
  $object->meta->add_attribute(
    $p => {
      is => 'ro',
      default => 'test',
      lazy => 1
    }
  );
}


package main;
my $a = Class1->new;
warn $a->Resource1; # must be 'test' but showing Moose::Meta::Attribute=HASH(0x333ca10)

Solution

  • You generated the attribute and its accessor, but you forgot to call the accessor. So code returns nothing on first call.

    Corrected example:

    sub AUTOLOAD {
        my $self = shift;
        our $AUTOLOAD;
        my $unknown_method_name = (split(/::/, $AUTOLOAD))[-1];
        require Class2; # generator class
        Class2->generate_one($self, $unknown_method_name);
        return $self->$unknown_method_name(@_);
    }