Why does "very bad practice" cancel new ones when using Moose?

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.

# Some pseudo code showing the logic of what I attempted
around BUILDARGS => sub {
    my ($orig, $self, %args) = @_;

    # loop through objects in list
    for my $object (@list) {

        # if $args used to define the new object
        # match the arguments of any object in the list
        # return the matched object

        # I want this to directly return the object
        # and skip the call to BUILD
    }

    return $self->orig(
        # Insert args here
    );
};

sub BUILD {
    my ($self) = @_;

    # I don't want this call to happen if the object already existed
    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.

# Some pseudo code showing the overridden constructor
sub new {
    my ($class, %args) = @_;

    # loop through objects in list
    for my $object (@list) {

        # if $args used to define the new object
        # match the arguments of any object in the list
        # return the matched object
    }

    # Build the object
    my $self = bless {
        # Insert args here
    }, $class;

    # Add the object to the list
    push @list, $object;
}

new , , , Moose, ?

+4
2

new, Moose, . , new, Moose "" .


, new :

has 'var' => (is => 'rw', isa => 'Str', => required => 1);

Moose , var.


, , , . ( ), "" . around, Moose, , Moose "" .

:

around new => sub {
    my ($orig, $class, %args) = @_;

    # loop through objects in list
    for my $object (@list) {

        # if $args used to define the new object
        # match the arguments of any object in the list
        # return the matched object without calling new
    }

    # Create a new object
    my $self = $class->orig(%args);

    # Add it to the list of objects.
    push @list, $self;
};

, , , .

: __PACKAGE__->meta->make_immutable('inline_constructor' => 0); .

+1

. , , . , , ,

+1

All Articles