porton
porton

Reputation: 5801

Perl Moo, dynamically generated accessors

I try to turn Perl closures into Moo accessors, as in the following code. Unfortunately the code works with Moose but throws an exception with Moo.

Please help me to write a Moo code with read and write accessors defined by Perl closures (not the default accessors which just read and store a simple value, but accessors reading and writing which should call my closures).

#!/usr/bin/perl

package X;
use Moo;

my $BusinessClass = "X";
my $Key = 'zz';

no strict 'refs';
*{"${BusinessClass}::access_$Key"} = sub { "Modified $Key" };
has $Key => ( is        => 'rw',
              required  => 0,
              accessor  => { $Key => \&{"${BusinessClass}::access_$Key"} },
              # predicate => { "has_$Key",\&{"${BusinessClass}::access2_$Key"} },
            );

my $obj = X->new;
print $obj->zz, "\n";

Upvotes: 1

Views: 313

Answers (1)

ikegami
ikegami

Reputation: 385887

Moo's has doesn't seem to have an accessor option.

#!/usr/bin/perl

package X;

use Moo;
use feature qw( say );

for my $attr_name (qw( zz )) {
   eval(<<'__EOS__' =~ s/ATTR_NAME/$attr_name/gr) or die($@);
      sub ATTR_NAME {
          my $self = shift;
          @_ ? $self->_set_ATTR_NAME($_[0]) : $self->_get_ATTR_NAME()
      }

      1;  # No exception
__EOS__

   has $attr_name => (
      is       => 'rw',
      required => 0,
      reader   => '_get_'.$attr_name,
      writer   => '_set_'.$attr_name,
   );
}

my $obj = X->new;
$obj->zz("abc");
say $obj->zz;

Untested.

Upvotes: 1

Related Questions