use B 'perlstring';
use Sub::Defer ();
-our $VERSION = '1.000001'; # 1.0.1
+our $VERSION = '1.000008'; # 1.0.8
$VERSION = eval $VERSION;
require Moo::sification;
my $target = caller;
my $class = shift;
strictures->import;
- return if $MAKERS{$target}; # already exported into this package
- $MAKERS{$target} = {};
+ if ($Moo::Role::INFO{$target} and $Moo::Role::INFO{$target}{is_role}) {
+ die "Cannot import Moo into a role";
+ }
+ $MAKERS{$target} ||= {};
_install_tracked $target => extends => sub {
$class->_set_superclasses($target, @_);
$class->_maybe_reset_handlemoose($target);
$class->_maybe_reset_handlemoose($target);
};
_install_tracked $target => has => sub {
- my ($name, %spec) = @_;
- $class->_constructor_maker_for($target)
- ->register_attribute_specs($name, \%spec);
- $class->_accessor_maker_for($target)
- ->generate_method($target, $name, \%spec);
- $class->_maybe_reset_handlemoose($target);
+ my ($name_proto, %spec) = @_;
+ my $name_isref = ref $name_proto eq 'ARRAY';
+ foreach my $name ($name_isref ? @$name_proto : $name_proto) {
+ # Note that when $name_proto is an arrayref, each attribute
+ # needs a separate \%specs hashref
+ my $spec_ref = $name_isref ? +{%spec} : \%spec;
+ $class->_constructor_maker_for($target)
+ ->register_attribute_specs($name, $spec_ref);
+ $class->_accessor_maker_for($target)
+ ->generate_method($target, $name, $spec_ref);
+ $class->_maybe_reset_handlemoose($target);
+ }
return;
};
foreach my $type (qw(before after around)) {
return;
};
}
+ return if $MAKERS{$target}{is_class}; # already exported into this package
+ $MAKERS{$target}{is_class} = 1;
{
no strict 'refs';
@{"${target}::ISA"} = do {
sub _set_superclasses {
my $class = shift;
my $target = shift;
- for (@_) {
- _load_module($_);
- if ($INC{"Role/Tiny.pm"} && $Role::Tiny::INFO{$_}) {
+ foreach my $superclass (@_) {
+ _load_module($superclass);
+ if ($INC{"Role/Tiny.pm"} && $Role::Tiny::INFO{$superclass}) {
require Carp;
- Carp::croak("Can't extend role '$_'");
+ Carp::croak("Can't extend role '$superclass'");
}
}
# Can't do *{...} = \@_ or 5.10.0's mro.pm stops seeing @ISA
no warnings 'once'; # piss off. -- mst
$Moo::HandleMoose::MOUSE{$target} = [
grep defined, map Mouse::Util::find_meta($_), @_
- ] if $INC{"Mouse.pm"};
+ ] if Mouse::Util->can('find_meta');
}
sub _maybe_reset_handlemoose {
.' '.$class.'->_constructor_maker_for($class,'.perlstring($target).');'."\n"
.' return $class->new(@_)'.";\n"
.' } elsif ($INC{"Moose.pm"} and my $meta = Class::MOP::get_metaclass_by_name($class)) {'."\n"
- .' return $meta->new_object(@_);'."\n"
+ .' return $meta->new_object($class->BUILDARGS(@_));'."\n"
.' }'."\n"
),
)
Unlike L<Mouse> this module does not aim at full compatibility with
L<Moose>'s surface syntax, preferring instead of provide full interoperability
-via the metaclass inflation capabilites described in L</MOO AND MOOSE>.
+via the metaclass inflation capabilities described in L</MOO AND MOOSE>.
For a full list of the minor differences between L<Moose> and L<Moo>'s surface
-syntax, see L</INCOMPATIBILITIES>.
+syntax, see L</INCOMPATIBILITIES WITH MOOSE>.
=head1 WHY MOO EXISTS
C<builder> to C<_build_${attribute_name}> to allow on-demand generated
attributes. This feature was my attempt to fix my incompetence when
originally designing C<lazy_build>, and is also implemented by
-L<MooseX::AttributeShortcuts>.
+L<MooseX::AttributeShortcuts>. There is, however, nothing to stop you
+using C<lazy> and C<builder> yourself with C<rwp> or C<rw> - it's just that
+this isn't generally a good idea so we don't provide a shortcut for it.
C<rwp> generates a reader like C<ro>, but also sets C<writer> to
C<_set_${attribute_name}> for attributes that are designed to be written
$self->$builder;
-If you set this to just C<1>, the predicate is automatically named
-C<_build_${attr_name}>. This feature comes from L<MooseX::AttributeShortcuts>.
+The following features come from L<MooseX::AttributeShortcuts>:
+
+If you set this to just C<1>, the builder is automatically named
+C<_build_${attr_name}>.
+
+If you set this to a coderef or code-convertible object, that variable will be
+installed under C<$class::_build_${attr_name}> and the builder set to the same
+name.
=item * C<clearer>
use Sub::Quote;
has foo => (
- is => quote_sub(q{ die "Not <3" unless $_[0] < 3 })
+ is => 'ro',
+ isa => quote_sub(q{ die "Not <3" unless $_[0] < 3 })
);
which will be inlined as
or to avoid localizing @_,
has foo => (
- is => quote_sub(q{ my ($val) = @_; die "Not <3" unless $val < 3 })
+ is => 'ro',
+ isa => quote_sub(q{ my ($val) = @_; die "Not <3" unless $val < 3 })
);
which will be inlined as
constructor. Moo does it automatically the first time ->new is called
on your class.
+An extension L<MooX::late> exists to ease translating Moose packages
+to Moo by providing a more Moose-like interface.
+
=head1 SUPPORT
Users' IRC: #moose on irc.perl.org
ilmari - Dagfinn Ilmari Mannsåker (cpan:ILMARI) <ilmari@ilmari.org>
+tobyink - Toby Inkster (cpan:TOBYINK) <tobyink@cpan.org>
+
+haarg - Graham Knop (cpan:HAARG) <haarg@cpan.org>
+
=head1 COPYRIGHT
Copyright (c) 2010-2011 the Moo L</AUTHOR> and L</CONTRIBUTORS>