After discovering AUTOLOAD, I wrote my accessors as (excerpt from Log::Procmail 0.05):
sub AUTOLOAD {
# don't DESTROY
return if $AUTOLOAD =~ /::DESTROY/;
# fetch the attribute name
$AUTOLOAD =~ /.*::(\w+)/;
my $attr = $1;
if ( $attr eq lc $attr ) { # accessors are lowercase
no strict 'refs';
# create the method
*{$AUTOLOAD} = sub {
my $self = shift;
@_ ? $self->{$attr} = shift: $self->{$attr};
};
# now do it
goto &{$AUTOLOAD};
}
}
This looks cargo-cultish, and I can't remember why I put that if ( $attr eq lc $attr ) line in the code.
Now I prefer generating the accessors from the beginning (this is an excerpt from Log::Procmail 0.06):
for my $attr (qw( from date subject size folder source ) ) {
no strict 'refs';
*{"Log::Procmail::Abstract::$attr"} = sub {
my $self = shift;
@_ ? $self->{$attr} = shift: $self->{$attr};
}
}
I tend to prefer this way of doing things:
What did I miss?
use base qw( Class::Accessor::Fast );
__PACKAGE__->mk_accesors(qw( from date subject size folder source ));
See: Class::Accessor
This has the advantage of being able to use them as lvalues, like in Perl 6:use Attribute::Property;
package My::Class;
sub foo : Property;
sub bar : Property;
sub baz : Property {/^\d+$/ }
instead of:$foo->bar =~ s/foo/bar/;
my ($temp = $foo->bar) =~ s/foo/bar/;
$foo->bar($temp);