On the Moose :: Manual :: BestPractices page :
Redefinition newis a very bad practice . Instead, you should use methods BUILDor BUILDARGSto do the same. When you override new, Moose can no longer embed a constructor when your class is unstable.
My question is: why is this considered a very bad practice?
I thought that the built-in constructor simply means that the constructor was defined in the same package as the class. If so, does this mean that if you override newinside this package, the constructor will still be considered an inline constructor? Please correct me if I am wrong. I do not quite understand the concept of what it means that the constructor will be "inline".
The reason I came across this question is because I am creating a script that builds a list of objects. If the user tries to create a new object that is identical to the one in the list, I want to stop Moosecreating a new object and simply return the link to the existing one.
When a new object is created, I want to click it in the list and return the new object. When an attempt is made to create an existing object, the existing object must be returned and not put on the list.
around BUILDARGS => sub {
my ($orig, $self, %args) = @_;
for my $object (@list) {
}
return $self->orig(
);
};
sub BUILD {
my ($self) = @_;
push @list, $self;
}
When creating a new object, I tried to use BUILDit to insert it into the list after creating it. The problem is that when I tried to create an existing object and use it BUILDARGSto return the existing object, it doesn’t seem to stop Moosethe call BUILDthat is trying to push the object into the list.
The only way I could get around this was to redefine newand return its existing object without creating a new one.
sub new {
my ($class, %args) = @_;
for my $object (@list) {
}
my $self = bless {
}, $class;
push @list, $object;
}
new , , , Moose, ?