tlm has asked for the wisdom of the Perl Monks concerning the following question:
Update: Problem solved. Thanks, BrowserUk.
Fellow monks,
Below is code for automatically generating accessor methods with an lvalue attribute.
According to the docs, attributes in general are not available for anonymous subs, which means that the common approach of generating methods by dynamically aliasing closures can't be used if one wants these methods to have an lvalue attribute.
The only alternative I can think of is eval'ing dynamically generated strings. I'm not crazy about this, but a prototype I threw together works well enough, so I thought I'd run it by you folks, in case there are pitfalls I have overlooked. Below is the code along with a brief demo. Your comments would be much appreciated.
# Accessor_Factory.pm use strict; use warnings; package Accessor_Factory; 1; # appease the wrath of require sub make_getsets { my @fields = @_; my $class = caller; for my $field ( @fields ) { my $code = <<EOCODE; { package $class; use Carp 'carp'; sub $field : lvalue { my \$self = shift; carp "Only first argument to method $field of class $class is +used" if \@_ > 1; \$self->{ $field } = shift if \@_; \$self->{ $field }; } } 1; EOCODE eval $code or die $@; } return; } __END__
# Foo.pm use strict; use warnings; package Foo; 1; BEGIN { use Accessor_Factory; Accessor_Factory::make_getsets( qw( bar baz ) ); } sub new { return bless +{}, shift; } __END__
# demo.pl use strict; use warnings; use Foo; my $foo = Foo->new(); $foo->bar = 1; print $foo->bar, "\n"; $foo->bar += 2; print $foo->bar, "\n"; $foo->bar( 5 ); print $foo->bar, "\n"; print $foo->baz = 8, "\n"; print $foo->baz *= 11, "\n"; print $foo->baz( 100 ), "\n"; __END__
1 3 5 8 88 100
Update: Added a few more cases to the demo.
the lowliest monk
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: RFC: Autogenerating lvalue methods
by BrowserUk (Patriarch) on Jul 01, 2005 at 19:39 UTC | |
by tlm (Prior) on Jul 01, 2005 at 19:51 UTC | |
|
Re: RFC: Autogenerating lvalue methods
by dragonchild (Archbishop) on Jul 01, 2005 at 18:47 UTC |