ZAmonk has asked for the wisdom of the Perl Monks concerning the following question:

Monks, Is it possible to retrieve the attribute name that is currently being set in a builder method - similar to what caller() does? Maybe an example will better explain what is required:
package This::That; use Moose; has 'FOO' => (is => 'rw', lazy => 1, builder=> '_build_generic'); has 'BAR' => (is => 'rw', lazy => 1, builder=> '_build_generic'); with qw(SQLConnection); sub _build_generic { my $self = shift; #my $attribute_name = $self->meta->???? - is it possible to determi +ne 'FOO' or 'BAR' is being set here ??? #my $sth = $self->dbh->prepare('select $attribute_name from table wh +ere x=? and y=?'); #$sth->execute(1,2); return $sth->fetchrow_array; }

The obvious alternative is to write separate builder methods for each attribute. However, this can lead to unnecessary repetition, where the only item that is changing is the attribute name.

Replies are listed 'Best First'.
Re: Retrieving attribute name for use in generic Moose builder method
by stvn (Monsignor) on Jul 01, 2009 at 18:46 UTC
    Monks, Is it possible to retrieve the attribute name that is currently being set in a builder method - similar to what caller() does?

    No, it is not possible to get that information. However I suggest you use the approach described below as it will not only reduce code duplication, but also make it that much easier to add similar attributes later on and in subclasses.

    package This::That; use Moose; has 'FOO' => (is => 'rw', lazy => 1, builder=> '_build_foo'); has 'BAR' => (is => 'rw', lazy => 1, builder=> '_build_bar'); with qw(SQLConnection); sub _build_foo { (shift)->_build_generic('FOO') } sub _build_bar { (shift)->_build_generic('BAR') } sub _build_generic { my ($self, $attribute_name) = @_; my $sth = $self->dbh->prepare('select $attribute_name from table whe +re x=? and y=?'); $sth->execute(1,2); return $sth->fetchrow_array; }
    Note too that this approach also makes it possible to have a custom FOO or BAR builder in a subclass. With your previous version you would have needed to change the builder method pointer and do other hackery that would lead to issues later on.

    -stvn