methods, as opposed to just the first one found. Requested by
Michael Schwern (RT #41119). (Dave Rolsky)
+ * Moose::Meta::Method::Constructor
+ - Moose will no longer inline a constructor for your class
+ unless it inherits its constructor from Moose::Object, and
+ will warn when it doesn't inline. If you want to force
+ inlining anyway, pass "replace_constructor => 1" to
+ make_immutable. Addresses RT #40968, reported by Jon
+ Swartz. (Dave Rolsky)
+
0.62_01 Wed, December 3, 2008
* Moose::Object
- use the method->execute API for BUILDALL
return $self;
}
+sub can_be_inlined {
+ my $self = shift;
+ my $metaclass = $self->associated_metaclass;
+
+ if ( my $constructor = $metaclass->find_method_by_name( $self->name ) ) {
+
+ my $expected_class = $self->_expected_constructor_class;
+
+ if ( $constructor->body != $expected_class->can('new') ) {
+ my $class = $metaclass->name;
+ warn "Not inlining a constructor for $class since it is not inheriting the default $expected_class constructor\n";
+
+ return 0;
+ }
+ else {
+ return 1;
+ }
+ }
+
+ # This would be a rather weird case where we have no constructor
+ # in the inheritance chain.
+ return 1;
+}
+
+# This is here so can_be_inlined can be inherited by MooseX modules.
+sub _expected_constructor_class {
+ return 'Moose::Object';
+}
+
## accessors
sub options { (shift)->{'options'} }
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More;
+
+eval "use Test::Output";
+plan skip_all => "Test::Output is required for this test" if $@;
+
+plan tests => 4;
+
+{
+ package NotMoose;
+
+ sub new {
+ my $class = shift;
+
+ return bless { not_moose => 1 }, $class;
+ }
+}
+
+{
+ package Foo;
+ use Moose;
+
+ extends 'NotMoose';
+
+ ::stderr_is(
+ sub { Foo->meta->make_immutable },
+ "Not inlining a constructor for Foo since it is not inheriting the default Moose::Object constructor\n",
+ 'got a warning that Foo may not have an inlined constructor'
+ );
+}
+
+is(
+ Foo->meta->find_method_by_name('new')->body,
+ NotMoose->can('new'),
+ 'Foo->new is inherited from NotMoose'
+);
+
+{
+ package Bar;
+ use Moose;
+
+ extends 'NotMoose';
+
+ ::stderr_is(
+ sub { Foo->meta->make_immutable( replace_constructor => 1 ) },
+ q{},
+ 'no warning when replace_constructor is true'
+ );
+}
+
+isnt(
+ Bar->meta->find_method_by_name('new')->body,
+ Moose::Object->can('new'),
+ 'Bar->new is not inherited from NotMoose because it was inlined'
+);