In Moose, how do I modify an attribute any time it is set?

moose, perl

Solution

I'm not sure what kind of modification you need, but you might be able to achieve what you need by using type coercion:

package Foo;
use Moose;

use Moose::Util::TypeConstraints;

subtype 'ModStr' 
    => as 'Str'
    => where { /^modified: /};

coerce 'ModStr'
    => from 'Str'
    => via { "modified: $_" };

has 'bar' => ( 
    isa => 'ModStr', 
    is  => 'rw', 
    coerce => 1,
);

If you use this approach, not all values will be modified. Anything that passes validation as a ModStr will be used directly:

my $f = Foo->new();
$f->bar('modified: bar');  # Set without modification

This weakness could be OK or it could make this approach unusable. In the right circumstances, it might even be an advantage.

Problem

If you have an attribute that needs to be modified any time it is set, is there a slick way of doing this short of writing the accessor yourself and mucking around directly with the content of `$self`, as done in this example? ``` package Foo; use Moose; has 'bar' => ( isa => 'Str', reader => 'get_bar', ); sub set_bar { my ($self, $bar) = @_; $self->{bar} = "modified: $bar"; } ``` I considered `trigger`, but it seemed to require the same approach. Is working directly with the hash reference in `$self` considered bad practice in Moose, or am I worrying about a non-issue?

Original source