My Moose class consumes a role which I'm not allowed to change. That role defines an attribute with a default. I need my class to have that attribute, but with a different default.
Is that possible?
All I could come up with is surrounding the "new" method with some of my own code, as follows:
around new => sub {
my ($orig, $self) = (shift, shift);
return $self->$orig(@_, the_attribute => $new_value);
}
But I'm not sure if surrounding new is valid, and was also hoping for something more elegant.
A better, simpler way is to write this in your class:
has '+the_attribute' => (
default => sub{1},
}
has
with a +
lets you override just a specific property of an attribute.
Much simpler than surrounding BUILDARGS.
You have the right idea, but you shouldn't override new
. Moose::Manual::BestPractices says:
Never override new
Overriding
new
is a very bad practice. Instead, you should use aBUILD
orBUILDARGS
methods to do the same thing. When you overridenew
, Moose can no longer inline a constructor when your class is immutabilized.
It's been a while since I've done this, but I think the following will do the trick:
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
return $self->$orig(
the_attribute => $new_value,
@_ == 1 ? %{ $_[0] } : @_,
);
};
Notes:
->new({ ... })
and ->new(...)
still work. You could use @_
instead of @_ == 1 ? %{ $_[0] } : @_
if you don't care about breaking ->new({ ... })
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With