+ - Automatic detection on non-Moo superclasses
+
0.9.3 Sun Dec 5 2010
- Fix _load_module to deal with pre-existing subpackages
$_[0]->{accessor_generator}
}
+sub construction_string {
+ my ($self) = @_;
+ $self->{construction_string} or 'bless({}, $class);'
+}
+
sub install_delayed {
my ($self) = @_;
my $package = $self->{package};
my $body = ' my $class = shift;'."\n";
$body .= $self->_generate_args;
$body .= $self->_check_required($spec);
- $body .= ' my $new = bless({}, $class);'."\n";
+ $body .= ' my $new = '.$self->construction_string.";\n";
$body .= $self->_assign_new($spec);
if ($into->can('BUILD')) {
require Method::Generate::BuildAll;
return unless $MAKERS{$target};
$MAKERS{$target}{constructor} ||= do {
require Method::Generate::Constructor;
+ my $con;
+
+ # using the -last- entry in @ISA means that classes created by
+ # Role::Tiny as N roles + superclass will still get the attributes
+ # from the superclass via the ->register_attribute_specs call later
+
+ if (my $super = do { no strict 'refs'; ${"${target}::ISA"}[-1] }) {
+ $con = $MAKERS{$super}{constructor} if $MAKERS{$super};
+ }
+ my $moo_constructor = !!$con || do {
+ my $t_new = $target->can('new');
+ $t_new and $t_new == Moo::Object->can('new');
+ };
+ require Moo::_mro unless $moo_constructor;
Method::Generate::Constructor
->new(
package => $target,
accessor_generator => do {
require Method::Generate::Accessor;
Method::Generate::Accessor->new;
- }
+ },
+ ($moo_constructor ? ()
+ : (construction_string => '$class->next::method(@_)'))
)
->install_delayed
- ->register_attribute_specs(do {
- my @spec;
- # using the -last- entry in @ISA means that classes created by
- # Role::Tiny as N roles + superclass will still get the attributes
- # from the superclass
- if (my $super = do { no strict 'refs'; ${"${target}::ISA"}[-1] }) {
- if (my $con = $MAKERS{$super}{constructor}) {
- @spec = %{$con->all_attribute_specs};
- }
- }
- @spec;
- });
+ ->register_attribute_specs(%{$con?$con->all_attribute_specs:{}})
}
}
--- /dev/null
+use strictures 1;
+use Test::More;
+
+{
+ package t::moo::extends_non_moo::base;
+
+ sub new {
+ my ($proto, $args) = @_;
+ bless $args, $proto;
+ }
+
+ sub to_app {
+ (shift)->{app};
+ }
+
+ package t::moo::extends_non_moo::middle;
+ use base qw(t::moo::extends_non_moo::base);
+
+ sub wrap {
+ my($class, $app) = @_;
+ $class->new({app => $app})
+ ->to_app;
+ }
+
+ package t::moo::extends_non_moo::moo;
+ use Moo;
+ extends 't::moo::extends_non_moo::middle';
+
+ package t::moo::extends_non_moo::moo_with_attr;
+ use Moo;
+ extends 't::moo::extends_non_moo::middle';
+ has 'attr' => (is=>'ro');
+}
+
+ok my $app = 100,
+ 'prepared $app';
+
+ok $app = t::moo::extends_non_moo::middle->wrap($app),
+ '$app from $app';
+
+is $app, 100,
+ '$app still 100';
+
+ok $app = t::moo::extends_non_moo::moo->wrap($app),
+ '$app from $app';
+
+is $app, 100,
+ '$app still 100';
+
+ok $app = t::moo::extends_non_moo::moo_with_attr->wrap($app),
+ '$app from $app';
+
+is $app, 100,
+ '$app still 100';
+
+done_testing();