perlattributesmoosemoo

Moo: Add attribute to another (non-current) package


The following is a simplified example of my real code:

#!/usr/bin/perl

package X;
use Moo;

sub add_attr_for_another_package {
  my ($package) = @_;
  eval "package $package";
  has 'q' => (is=>'rw', default=>123);
}

package Y;
use Moo;

X::add_attr_for_another_package('Y');

my $obj = Y->new;
print $obj->q, "\n";

I try to add an attribute to package Y from a function defined in package X. This does not work:

$ ./test.pl 
Can't locate object method "q" via package "Y" at ./test.pl line 18.

Please help how can I add an attribute to a package from a method defined in another package.

Should I switch to Moose?


Solution

  • package affects the package into which code is compiled. It obviously won't affect code that's already been compiled (e.g. the call to has)! In other words, the call to has has to be compiled when the package directive is in effect to be affected by it.

    sub add_attr_for_another_package {
      my ($package) = @_;
      eval("
        package $package;
        has 'q' => (is=>'rw', default=>123);
        return 1;
      ")
        or die $@;
    }