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);