@@ -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