Bro. Doug has asked for the wisdom of the Perl Monks concerning the following question:

Esteemed monks,

I'd like to keep a list of accessor methods, then declare all the subs off the list. I think that would be a low maintenance way of designing my object.

This here code doesn't work, but it illustrates what I'm trying to do and is (hopefully) correctable:
package Bro::Doug ; use strict ; use warnings ; use warnings::register ; BEGIN{ no strict 'subs' ; my @ACCESSOR_METHODS = qw( one two three ) ; foreach my $i ( @ACCESSOR_METHODS ){ sub $i { my $self = shift ; if ( @_ ) { $self->{ uc $i } = shift @_ } return $self->{ uc $i } ; } } } sub new { my $class = shift ; my $self = {} ; bless ($self, $class) ; return $self ; } 1;
I check it like this and get an error message.
% perl -cw Doug.pm > Illegal declaration of anonymous subroutine at Doug.pm line 58.
Does anyone know how to make this work right?

Peace monks,
Bro. Doug :wq

Replies are listed 'Best First'.
Re: declaring accessor methods from a list
by Joost (Canon) on Apr 26, 2007 at 22:32 UTC
Re: declaring accessor methods from a list
by Trizor (Pilgrim) on Apr 26, 2007 at 22:38 UTC

    sub $name {} isn't working the way you expect it to because named subs are picked up during the compilation of the BEGIN block.

    What you want to do is edit the GLOB with the name of your accessor in a fasion similar to this:

    BEGIN { my @accessors = qw(one two foo); foreach my $methname (@accessors) { no strict 'refs'; *$methname = sub { # accessor sub }; } }

    As an alternative to rolling your own autogenerator you could look on the CPAN as there are several mentioned elsewhere in this thread.

      Thank you.

      I tried that and it worked. And yes, I could be looking for prior art. I'm also just interested in knowing how this thing is done (a perlmonks party trick?).

      After I get this working and tested from a test.pl, I'll post it up with corrections.

      Peace monks,
      Bro. Doug :wq
        perlmonks is full of prior art
Re: declaring accessor methods from a list
by GrandFather (Saint) on Apr 26, 2007 at 22:13 UTC
Re: declaring accessor methods from a list
by AK108 (Friar) on Apr 27, 2007 at 01:22 UTC
    I use Class::Accessor to generate my accessors, and it's one of a handful of modules to provide this functionality.
Re: declaring accessor methods from a list
by ferreira (Chaplain) on Apr 27, 2007 at 11:31 UTC
    As AK108 pointed out, Class::Accessor is a nice module to do what you want and like it a lot as well. With it, your code would turn to be:
    package Bro::Doug ; use strict ; use warnings ; use base qw(Class::Accessor); __PACKAGE__->mk_ro_accessors( qw(one two three) ); 1;
    and you will get the accessors and the new constructor for free.