title: Why is it "very bad practice" to override new when using Moose?
body: <p>From the <a href="http://search.cpan.org/dist/Moose/lib/Moose/Manual/BestPractices.pod#Never_override_new" rel="nofollow">Moose::Manual::BestPractices</a> page:</p>
  
  <blockquote>
    <p>Overriding <code>new</code> is a <strong>very bad practice</strong>. Instead, you should use a <code>BUILD</code> or <code>BUILDARGS</code> methods to do the same thing. When you override <code>new</code>, Moose can no longer inline a constructor when your class is immutabilized.</p>
  </blockquote>
  
  <p><strong>My question is why is this considered very bad practice?</strong></p>
  
  <p>I thought an "inline" constructor just meant that the constructor was defined in the same package as the class.  If this is true wouldn't it mean that if you overrode <code>new</code> within that package the constructor would still be considered an "inline" constructor?  Please correct me if I'm wrong.  I don't fully understand the concept of what it means for a constructor to be "inline."</p>
  
  <hr>
  
  <p>The reason I came across this question is because I'm creating a script that builds a list of objects.  If a user attempts to create a new object that is identical to one in the list I want to stop <code>Moose</code> from creating a new object and just return a reference to the existing one.</p>
  
  <p>When a new object is created I want to push it onto the list and return the new object.  When an attempt is made to create existing object the existing object should be returned and not pushed onto the list. </p>
  
  <pre><code># Some pseudo code showing the logic of what I attempted
  around BUILDARGS =&gt; 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-&gt;orig(
          # Insert args here
      );
  };
  
  sub BUILD {
      my ($self) = @_;
  
      # I don't want this call to happen if the object already existed
      push @list, $self;
  }   
  </code></pre>
  
  <p>When creating a new object I attempted to use <code>BUILD</code> to push it onto the list once it is created.  The problem is when I attempted to create an existing object and use <code>BUILDARGS</code> to return the existing object doesn't seem to stop <code>Moose</code> from calling <code>BUILD</code> which attempts to push the object onto the list.</p>
  
  <p>The only way I was able to get around this was to override <code>new</code> and have it return the existing object without creating a new one.</p>
  
  <pre><code># 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;
  }
  </code></pre>
  
  <p>Overriding <code>new</code> worked, but if it really is such a horrible idea, as the <code>Moose</code> documentation seems to suggest, is there a better way to do it?</p>