The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 012
META.json 34
META.yml 34
Makefile.PL 48
README 33
lib/Method/Generate/Accessor.pm 12
lib/Method/Generate/BuildAll.pm 12
lib/Method/Generate/DemolishAll.pm 12
lib/Moo/HandleMoose/_TypeMap.pm 36
lib/Moo/Role.pm 427
lib/Moo/_Utils.pm 11
lib/Moo.pm 912
lib/Sub/Defer.pm 22
lib/Sub/Quote.pm 22
t/compose-roles.t 020
t/sub-and-handles.t 1010
xt/moose-extend-moo.t 2271
xt/test-my-dependents.t 97
18 files changed (This is a version diff) 78195
@@ -1,5 +1,17 @@
 Revision history for Moo
 
+1.006001 - 2014-10-22
+  - Name the ->DOES method installed by Role::Tiny
+  - don't apply threading workarounds on non-threaded perls, even if module for
+    it is loaded by something
+  - avoid loading base.pm and just set @ISA manually
+  - fix some Pod links to Class::Method::Modifiers
+  - fix applying roles with multiple attributes with defaults to objects
+    (RT#99217)
+  - fix Moose inheriting from a Moo class that inherits from a non-M* class
+    when the Moose class is not made immutable
+  - fix ->does method on Moose child classes of Moo classes
+
 1.006000 - 2014-08-16
   - support coerce => 1 in attributes, taking the coercion from the isa option
     if it is an object that supports the coerce or coercion method.
@@ -4,7 +4,7 @@
       "mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.141520",
+   "generated_by" : "ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.142690",
    "license" : [
       "perl_5"
    ],
@@ -49,9 +49,10 @@
          "requires" : {
             "Class::Method::Modifiers" : "1.1",
             "Devel::GlobalDestruction" : "0.11",
+            "Exporter" : "5.57",
             "Import::Into" : "1.002",
             "Module::Runtime" : "0.014",
-            "Role::Tiny" : "1.003003",
+            "Role::Tiny" : "1.003004",
             "Scalar::Util" : "0",
             "perl" : "5.006",
             "strictures" : "1.004003"
@@ -83,7 +84,7 @@
       },
       "x_IRC" : "irc://irc.perl.org/#moose"
    },
-   "version" : "1.006000",
+   "version" : "1.006001",
    "x_authority" : "cpan:MSTROUT",
    "x_breaks" : {
       "HTML::Restrict" : "== 2.1.5"
@@ -8,7 +8,7 @@ build_requires:
 configure_requires:
   ExtUtils::MakeMaker: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.141520'
+generated_by: 'ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.142690'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -24,9 +24,10 @@ recommends:
 requires:
   Class::Method::Modifiers: '1.1'
   Devel::GlobalDestruction: '0.11'
+  Exporter: '5.57'
   Import::Into: '1.002'
   Module::Runtime: '0.014'
-  Role::Tiny: '1.003003'
+  Role::Tiny: '1.003004'
   Scalar::Util: '0'
   perl: '5.006'
   strictures: '1.004003'
@@ -35,7 +36,7 @@ resources:
   bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=Moo
   license: http://dev.perl.org/licenses/
   repository: https://github.com/moose/Moo.git
-version: '1.006000'
+version: '1.006001'
 x_authority: cpan:MSTROUT
 x_breaks:
   HTML::Restrict: '== 2.1.5'
@@ -25,11 +25,12 @@ my %META = (
         'Class::Method::Modifiers'  => 1.10,  # for RT#80194
         'strictures'                => 1.004003,
         'Module::Runtime'           => 0.014, # for RT#86394
-        'Role::Tiny'                => 1.003003,
+        'Role::Tiny'                => 1.003004,
         'Devel::GlobalDestruction'  => 0.11,  # for RT#78617
         'Import::Into'              => 1.002,
         'Scalar::Util'              => 0,
         'perl'                      => 5.006,
+        'Exporter'                  => 5.57,  # Import 'import'
       },
       recommends => {
         'Class::XSAccessor'         => 1.18,
@@ -75,7 +76,7 @@ my %MM_ARGS = (
   realclean => { FILES => 'Distar/' },
 );
 
-##############################################################################
+## BOILERPLATE ###############################################################
 require ExtUtils::MakeMaker;
 (do 'maint/Makefile.PL.include' or die $@) unless -f 'META.yml';
 
@@ -86,8 +87,10 @@ my $mymeta_broken = $mymeta && $eumm_version < 6.57_07;
 
 ($MM_ARGS{NAME} = $META{name}) =~ s/-/::/g;
 ($MM_ARGS{VERSION_FROM} = "lib/$MM_ARGS{NAME}.pm") =~ s{::}{/}g;
-$MM_ARGS{LICENSE} = $META{license}
-  if $eumm_version >= 6.30;
+$META{license} = [ $META{license} ]
+  if $META{license} && !ref $META{license};
+$MM_ARGS{LICENSE} = $META{license}[0]
+  if $META{license} && $eumm_version >= 6.30;
 $MM_ARGS{NO_MYMETA} = 1
   if $mymeta_broken;
 $MM_ARGS{META_ADD} = { 'meta-spec' => { version => 2 }, %META }
@@ -114,3 +117,4 @@ delete $MM_ARGS{CONFIGURE_REQUIRES}
   if $eumm_version < 6.51_03;
 
 ExtUtils::MakeMaker::WriteMakefile(%MM_ARGS);
+## END BOILERPLATE ###########################################################
@@ -469,19 +469,19 @@ IMPORTED SUBROUTINES
   before
      before foo => sub { ... };
 
-    See "before method(s) => sub { ... }" in Class::Method::Modifiers for
+    See "before method(s) => sub { ... };" in Class::Method::Modifiers for
     full documentation.
 
   around
      around foo => sub { ... };
 
-    See "around method(s) => sub { ... }" in Class::Method::Modifiers for
+    See "around method(s) => sub { ... };" in Class::Method::Modifiers for
     full documentation.
 
   after
      after foo => sub { ... };
 
-    See "after method(s) => sub { ... }" in Class::Method::Modifiers for
+    See "after method(s) => sub { ... };" in Class::Method::Modifiers for
     full documentation.
 
 SUB QUOTE AWARE
@@ -2,7 +2,8 @@ package Method::Generate::Accessor;
 
 use strictures 1;
 use Moo::_Utils;
-use base qw(Moo::Object);
+use Moo::Object ();
+our @ISA = qw(Moo::Object);
 use Sub::Quote qw(quote_sub quoted_from_sub quotify);
 use Scalar::Util 'blessed';
 use overload ();
@@ -1,7 +1,8 @@
 package Method::Generate::BuildAll;
 
 use strictures 1;
-use base qw(Moo::Object);
+use Moo::Object ();
+our @ISA = qw(Moo::Object);
 use Sub::Quote qw(quote_sub quotify);
 use Moo::_Utils;
 
@@ -1,7 +1,8 @@
 package Method::Generate::DemolishAll;
 
 use strictures 1;
-use base qw(Moo::Object);
+use Moo::Object ();
+our @ISA = qw(Moo::Object);
 use Sub::Quote qw(quote_sub quotify);
 use Moo::_Utils;
 
@@ -8,6 +8,7 @@ our %TYPE_MAP;
 package Moo::HandleMoose::_TypeMap;
 
 use Scalar::Util ();
+use Config;
 
 our %WEAK_TYPES;
 
@@ -65,8 +66,10 @@ sub DESTROY {
   %TYPE_MAP = %types;
 }
 
-my @types = %TYPE_MAP;
-tie %TYPE_MAP, __PACKAGE__;
-%TYPE_MAP = @types;
+if ($Config{useithreads}) {
+  my @types = %TYPE_MAP;
+  tie %TYPE_MAP, __PACKAGE__;
+  %TYPE_MAP = @types;
+}
 
 1;
@@ -3,10 +3,10 @@ package Moo::Role;
 use strictures 1;
 use Moo::_Utils;
 use Role::Tiny ();
-use base qw(Role::Tiny);
+our @ISA = qw(Role::Tiny);
 use Import::Into;
 
-our $VERSION = '1.006000';
+our $VERSION = '1.006001';
 $VERSION = eval $VERSION;
 
 require Moo::sification;
@@ -323,7 +323,7 @@ sub apply_roles_to_object {
 
       my $specs = $con_gen->all_attribute_specs;
 
-      my $assign = '';
+      my $assign = "{no warnings 'void';\n";
       my %captures;
       foreach my $name ( keys %attrs ) {
         my $spec = $specs->{$name};
@@ -333,11 +333,12 @@ sub apply_roles_to_object {
           my ($code, $pop_cap)
             = $m->generate_use_default('$_[0]', $name, $spec, $has);
 
-          $assign .= $code;
+          $assign .= $code . ";\n";
           @captures{keys %$has_cap, keys %$pop_cap}
             = (values %$has_cap, values %$pop_cap);
         }
       }
+      $assign .= "}";
       Sub::Quote::quote_sub($assign, \%captures);
     }
     else {
@@ -361,6 +362,28 @@ sub _install_single_modifier {
   _install_modifier(@args);
 }
 
+sub _install_does {
+    my ($me, $to) = @_;
+
+    # If Role::Tiny actually installed the DOES, give it a name
+    my $new = $me->SUPER::_install_does($to) or return;
+    return _name_coderef("${to}::DOES", $new);
+}
+
+sub does_role {
+  my ($proto, $role) = @_;
+  return 1
+    if Role::Tiny::does_role($proto, $role);
+  my $meta;
+  if ($INC{'Moose.pm'}
+      and $meta = Class::MOP::class_of($proto)
+      and ref $meta ne 'Moo::HandleMoose::FakeMetaClass'
+  ) {
+    return $meta->does_role($role);
+  }
+  return 0;
+}
+
 sub _handle_constructor {
   my ($me, $to, $role) = @_;
   my $attr_info = $INFO{$role} && $INFO{$role}{attributes};
@@ -12,7 +12,7 @@ use strictures 1;
 use Module::Runtime qw(use_package_optimistically module_notional_filename);
 
 use Devel::GlobalDestruction ();
-use base qw(Exporter);
+use Exporter qw(import);
 use Moo::_mro;
 use Config;
 
@@ -4,7 +4,7 @@ use strictures 1;
 use Moo::_Utils;
 use Import::Into;
 
-our $VERSION = '1.006000';
+our $VERSION = '1.006001';
 $VERSION = eval $VERSION;
 
 require Moo::sification;
@@ -190,7 +190,10 @@ sub _constructor_maker_for {
           .'        '.$class.'->_constructor_maker_for($class);'."\n"
           .'        return $class->new(@_)'.";\n"
           .'      } elsif ($INC{"Moose.pm"} and my $meta = Class::MOP::get_metaclass_by_name($class)) {'."\n"
-          .'        return $meta->new_object($class->BUILDARGS(@_));'."\n"
+          .'        return $meta->new_object('."\n"
+          .'          $class->can("BUILDARGS") ? $class->BUILDARGS(@_)'."\n"
+          .'                      : $class->Moo::Object::BUILDARGS(@_)'."\n"
+          .'        );'."\n"
           .'      }'."\n"
         ),
       )
@@ -711,21 +714,21 @@ possible extensibility.
 
  before foo => sub { ... };
 
-See L<< Class::Method::Modifiers/before method(s) => sub { ... } >> for full
+See L<< Class::Method::Modifiers/before method(s) => sub { ... }; >> for full
 documentation.
 
 =head2 around
 
  around foo => sub { ... };
 
-See L<< Class::Method::Modifiers/around method(s) => sub { ... } >> for full
+See L<< Class::Method::Modifiers/around method(s) => sub { ... }; >> for full
 documentation.
 
 =head2 after
 
  after foo => sub { ... };
 
-See L<< Class::Method::Modifiers/after method(s) => sub { ... } >> for full
+See L<< Class::Method::Modifiers/after method(s) => sub { ... }; >> for full
 documentation.
 
 =head1 SUB QUOTE AWARE
@@ -929,13 +932,13 @@ to Moo by providing a more Moose-like interface.
 
 Users' IRC: #moose on irc.perl.org
 
-=for html <a href="http://chat.mibbit.com/#moose@irc.perl.org">(click for
-instant chatroom login)</a>
+=for :html
+L<(click for instance chatroom login)|http://chat.mibbit.com/#moose@irc.perl.org>
 
 Development and contribution IRC: #web-simple on irc.perl.org
 
-=for html <a href="http://chat.mibbit.com/#web-simple@irc.perl.org">(click for
-instant chatroom login)</a>
+=for :html
+L<(click for instance chatroom login)|http://chat.mibbit.com/#web-simple@irc.perl.org>
 
 Bugtracker: L<https://rt.cpan.org/Public/Dist/Display.html?Name=Moo>
 
@@ -1,11 +1,11 @@
 package Sub::Defer;
 
 use strictures 1;
-use base qw(Exporter);
+use Exporter qw(import);
 use Moo::_Utils;
 use Scalar::Util qw(weaken);
 
-our $VERSION = '1.006000';
+our $VERSION = '1.006001';
 $VERSION = eval $VERSION;
 
 our @EXPORT = qw(defer_sub undefer_sub undefer_all);
@@ -6,13 +6,13 @@ sub _clean_eval { eval $_[0] }
 
 use Sub::Defer;
 use Scalar::Util qw(weaken);
-use base qw(Exporter);
+use Exporter qw(import);
 use B ();
 BEGIN {
   *_HAVE_PERLSTRING = defined &B::perlstring ? sub(){1} : sub(){0};
 }
 
-our $VERSION = '1.006000';
+our $VERSION = '1.006001';
 $VERSION = eval $VERSION;
 
 our @EXPORT = qw(quote_sub unquote_sub quoted_from_sub qsub);
@@ -114,5 +114,25 @@ like exception {
 }, qr/Can't apply .* missing attr2/,
   'create_class_with_roles accepts attributes for requirements';
 
+{
+  package RoleWith2Attrs;
+  use Moo::Role;
+
+  has attr1 => (is => 'ro', default => -1);
+  has attr2 => (is => 'ro', default => -2);
+}
+
+foreach my $combo (
+  [qw(RoleWithAttr RoleWithAttr2)],
+  [qw(RoleWith2Attrs)],
+) {
+  is exception {
+    my $o = Moo::Role->apply_roles_to_object(
+      EmptyClass->new, @$combo);
+    is($o->attr1, -1, 'first attribute works');
+    is($o->attr2, -2, 'second attribute works');
+  }, undef, "apply_roles_to_object with multiple attrs with defaults (@$combo)";
+}
+
 
 done_testing;
@@ -34,7 +34,7 @@ use Test::More;
 
    sub _bar { 'extended' }
 
-   package A;
+   package First;
 
    use Moo;
    extends 'ConsumesDelegateToBar';
@@ -42,7 +42,7 @@ use Test::More;
 
    has '+_barrer' => ( is => 'rw' );
 
-   package B;
+   package Second;
 
    use Moo;
    extends 'ConsumesDelegateToBar';
@@ -51,7 +51,7 @@ use Test::More;
 
    has '+_barrer' => ( is => 'rw' );
 
-   package D;
+   package Fourth;
 
    use Moo;
    extends 'ConsumesDelegateToBar';
@@ -62,7 +62,7 @@ use Test::More;
       is => 'rw',
       handles => { _baz => 'bar' },
    );
-   package C;
+   package Third;
 
    use Moo;
    extends 'ConsumesDelegateToBar';
@@ -74,12 +74,12 @@ use Test::More;
    );
 }
 
-is(A->new->_bar, 'extended', 'overriding delegate method with role works');
-is(D->new->_bar, 'extended', '... even when you specify other delegates in subclass');
-is(D->new->_baz, 'unextended!', '... and said other delegate still works');
-is(B->new->_bar, 'extended', 'overriding delegate method directly works');
-is(C->new->_bar, 'extended', '... even when you specify other delegates in subclass');
-is(C->new->_baz, 'unextended!', '... and said other delegate still works');
+is(First->new->_bar, 'extended', 'overriding delegate method with role works');
+is(Fourth->new->_bar, 'extended', '... even when you specify other delegates in subclass');
+is(Fourth->new->_baz, 'unextended!', '... and said other delegate still works');
+is(Second->new->_bar, 'extended', 'overriding delegate method directly works');
+is(Third->new->_bar, 'extended', '... even when you specify other delegates in subclass');
+is(Third->new->_baz, 'unextended!', '... and said other delegate still works');
 
 done_testing;
 
@@ -1,36 +1,85 @@
 use strict;
 use warnings;
+use Test::More;
+use Test::Fatal;
 
-
-{
-    package Parent;
-    use Moo;
-    has message => ( is => 'ro', required => 1 ),
+BEGIN {
+  package Parent;
+  use Moo;
+  has message => ( is => 'ro', required => 1 ),
 }
 
-{
-    package Child;
-    use Moose;
-    extends 'Parent';
-    use Moose::Util::TypeConstraints;
-    use namespace::clean;   # <-- essential
-    has message => (
-        is => 'ro', isa => 'Str',
-        lazy => 1,
-        default => sub { 'overridden message sub here' },
-    );
+BEGIN {
+  package Child;
+  use Moose;
+  extends 'Parent';
+  use Moose::Util::TypeConstraints;
+  use namespace::clean;   # <-- essential
+  has message => (
+    is => 'ro', isa => 'Str',
+    lazy => 1,
+    default => sub { 'overridden message sub here' },
+  );
 }
+# without namespace::clean, gives the (non-fatal) warning:
+# You are overwriting a locally defined function (message) with an accessor
+# ...because Moose::Util::TypeConstraints exports a 'message' sub!
 
 my $obj = Child->new(message => 'custom message');
 
-use Test::More;
 is($obj->message, 'custom message', 'accessor works');
 
-done_testing;
+BEGIN {
+  package Role1;
+  use Moo::Role;
+}
 
-__END__
+BEGIN {
+  package Role2;
+  use Moose::Role;
+}
+
+BEGIN {
+  package Class1;
+  use Moo;
+  with 'Role1';
+}
 
-without namespace::clean, gives the (non-fatal) warning:
-You are overwriting a locally defined function (message) with an accessor
+BEGIN {
+  package Class2;
+  use Moose;
+  extends 'Class1';
+  with 'Role2';
+}
 
-...because Moose::Util::TypeConstraints exports a 'message' sub!
+ok +Class2->does('Role1'), "Moose child does parent's composed roles";
+ok +Class2->does('Role2'), "Moose child does child's composed roles";
+
+BEGIN {
+  package NonMooParent;
+  sub new {
+    bless {}, $_[0];
+  }
+}
+BEGIN {
+  package MooChild;
+  use Moo;
+  extends 'NonMooParent';
+  has attr1 => (is => 'ro');
+  with 'Role1';
+}
+BEGIN {
+  package MooseChild;
+  use Moose;
+  extends 'MooChild';
+  with 'Role2';
+  has attr2 => (is => 'ro');
+}
+
+is exception { MooseChild->new }, undef, 'NonMoo->Moo->Moose(mutable) works';
+MooseChild->meta->make_immutable;
+is exception { MooseChild->new }, undef, 'NonMoo->Moo->Moose(immutable) works';
+
+ok +MooseChild->does('Role2'), "Moose child does parent's composed roles with non-Moo ancestor";
+
+done_testing;
@@ -19,7 +19,8 @@ END_HELP
 }
 
 use Test::DependentModules qw( test_module );
-use MetaCPAN::API;
+use JSON::PP;
+use HTTP::Tiny;
 use List::Util ();
 use Cwd ();
 use Config;
@@ -35,9 +36,9 @@ $ENV{PERL5LIB} = join($Config{path_sep}, @extra_libs, $ENV{PERL5LIB}||());
 # avoid any modules that depend on these
 my @bad_prereqs = qw(Gtk2 Padre Wx);
 
-my $mcpan = MetaCPAN::API->new;
-my $res = $mcpan->post(
-  '/search/reverse_dependencies/Moo' => {
+my $res = decode_json(HTTP::Tiny->new->post(
+  'http://api.metacpan.org/v0/search/reverse_dependencies/Moo',
+  { content => encode_json({
     query => {
       filtered => {
         query => { "match_all" => {} },
@@ -56,8 +57,8 @@ my $res = $mcpan->post(
     },
     size => 5000,
     fields => ['distribution', 'provides', 'metadata.provides'],
-  },
-);
+  }) },
+)->{content});
 
 my %bad_dist;
 my $sec_reason;
@@ -145,8 +146,6 @@ if ($show) {
 
 plan tests => scalar @modules;
 for my $module (@modules) {
-  local $TODO = $todo_module{$module} || '???'
-    if exists $todo_module{$module};
   SKIP: {
     local $TODO = $todo_module{$module} || '???'
       if exists $todo_module{$module};
@@ -156,7 +155,6 @@ for my $module (@modules) {
   }
 }
 
-
 __DATA__
 
 # TODO: broken