use B 'perlstring';
use Sub::Defer ();
-our $VERSION = '1.000008'; # 1.0.8
+our $VERSION = '1.003001';
$VERSION = eval $VERSION;
require Moo::sification;
my $target = caller;
my $class = shift;
strictures->import;
- if ($Moo::Role::INFO{$target} and $Moo::Role::INFO{$target}{is_role}) {
+ if ($Role::Tiny::INFO{$target} and $Role::Tiny::INFO{$target}{is_role}) {
die "Cannot import Moo into a role";
}
$MAKERS{$target} ||= {};
$class->_maybe_reset_handlemoose($target);
};
_install_tracked $target => has => sub {
- 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
+ my $name_proto = shift;
+ my @name_proto = ref $name_proto eq 'ARRAY' ? @$name_proto : $name_proto;
+ if (@_ % 2 != 0) {
+ require Carp;
+ Carp::croak("Invalid options for " . join(', ', map "'$_'", @name_proto)
+ . " attribute(s): even number of arguments expected, got " . scalar @_)
+ }
+ my %spec = @_;
+ foreach my $name (@name_proto) {
+ # Note that when multiple attributes specified, each attribute
# needs a separate \%specs hashref
- my $spec_ref = $name_isref ? +{%spec} : \%spec;
+ my $spec_ref = @name_proto > 1 ? +{%spec} : \%spec;
$class->_constructor_maker_for($target)
->register_attribute_specs($name, $spec_ref);
$class->_accessor_maker_for($target)
Moo->_constructor_maker_for($target)
->register_attribute_specs(%{$old->all_attribute_specs});
}
+ elsif (!$target->isa('Moo::Object')) {
+ Moo->_constructor_maker_for($target);
+ }
no warnings 'once'; # piss off. -- mst
$Moo::HandleMoose::MOUSE{$target} = [
grep defined, map Mouse::Util::find_meta($_), @_
$MAKERS{$target}{accessor} ||= do {
my $maker_class = do {
if (my $m = do {
- if (my $defer_target =
+ if (my $defer_target =
(Sub::Defer::defer_info($target->can('new'))||[])->[0]
) {
my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/);
} else {
$moo_constructor = 1; # no other constructor, make a Moo one
}
- };
+ }
($con ? ref($con) : 'Method::Generate::Constructor')
->new(
package => $target,
construction_string => (
$moo_constructor
? ($con ? $con->construction_string : undef)
- : ('$class->'.$target.'::SUPER::new(@_)')
+ : ('$class->'.$target.'::SUPER::new($class->can(q[FOREIGNBUILDARGS]) ? $class->FOREIGNBUILDARGS(@_) : @_)')
),
subconstructor_handler => (
' if ($Moo::MAKERS{$class}) {'."\n"
=head1 NAME
-Moo - Minimalist Object Orientation (with Moose compatiblity)
+Moo - Minimalist Object Orientation (with Moose compatibility)
=head1 SYNOPSIS
to use them in L<Moose> code without anybody ever noticing you aren't using
L<Moose> everywhere.
+L<Moo> will also create L<Moose type constraints|Moose::Manual::Types> for
+classes and roles, so that C<< isa => 'MyClass' >> and C<< isa => 'MyRole' >>
+work the same as for L<Moose> classes and roles.
+
Extending a L<Moose> class or consuming a L<Moose::Role> will also work.
So will extending a L<Mouse> class or consuming a L<Mouse::Role> - but note
currently global and turns the mechanism off entirely so don't put this
in library code.
+=head1 MOO AND CLASS::XSACCESSOR
+
+If a new enough version of L<Class::XSAccessor> is available, it
+will be used to generate simple accessors, readers, and writers for
+a speed boost. Simple accessors are those without lazy defaults,
+type checks/coercions, or triggers. Readers and writers generated
+by L<Class::XSAccessor> will behave slightly differently: they will
+reject attempts to call them with the incorrect number of parameters.
+
=head1 MOO VERSUS ANY::MOOSE
L<Any::Moose> will load L<Mouse> normally, and L<Moose> in a program using
This method should always return a hash reference of named options.
+=head2 FOREIGNBUILDARGS
+
+If you are inheriting from a non-Moo class, the arguments passed to the parent
+class constructor can be manipulated by defining a C<FOREIGNBUILDARGS> method.
+It will receive the same arguments as C<BUILDARGS>, and should return a list
+of arguments to pass to the parent class constructor.
+
=head2 BUILD
Define a C<BUILD> method on your class and the constructor will automatically
Declares an attribute for the class.
+ package Foo;
+ use Moo;
+ has 'attr' => (
+ is => 'ro'
+ );
+
+ package Bar;
+ use Moo;
+ extends 'Foo';
+ has '+attr' => (
+ default => sub { "blah" },
+ );
+
+Using the C<+> notation, it's possible to override an attribute.
+
The options for C<has> are as follows:
=over 2
die "$_[0] is not a number!" unless looks_like_number $_[0]
},
+Note that the return value is ignored, only whether the sub lives or
+dies matters.
+
L<Sub::Quote aware|/SUB QUOTE AWARE>
Since L<Moo> does B<not> run the C<isa> check before C<coerce> if a coercion
do something like the following:
coerce => sub {
- $_[0] + 1 unless $_[0] % 2
+ $_[0] % 2 ? $_[0] : $_[0] + 1
},
Note that L<Moo> will always fire your coercion: this is to permit
if the attribute is lazy, when the attribute is first retrieved if no
value has yet been provided.
+If a simple scalar is provided, it will be inlined as a string. Any non-code
+reference (hash, array) will result in an error - for that case instead use
+a code reference that returns the desired value.
+
Note that if your default is fired during new() there is no guarantee that
other attributes have been populated yet so you should not rely on their
existence.
If you set this to just C<1>, the predicate is automatically named
C<has_${attr_name}> if your attribute's name does not start with an
-underscore, or <_has_${attr_name_without_the_underscore}> if it does.
+underscore, or C<_has_${attr_name_without_the_underscore}> if it does.
This feature comes from L<MooseX::AttributeShortcuts>.
=item * C<builder>
initialization name. C<undef> means that passing the value in on instantiation
is ignored.
+=item * C<moosify>
+
+Takes either a coderef or array of coderefs which is meant to transform the
+given attributes specifications if necessary when upgrading to a Moose role or
+class. You shouldn't need this by default, but is provided as a means of
+possible extensibility.
+
=back
=head2 before
probably the weakest part of Moose design-wise.
C<initializer> is not supported in core since the author considers it to be a
-bad idea but may be supported by an extension in future. Meanwhile C<trigger> or
+bad idea and Moose best practices recommend avoiding it. Meanwhile C<trigger> or
C<coerce> are more likely to be able to fulfill your needs.
There is no meta object. If you need this level of complexity you wanted
L<Devel::Dwarn> into C<main::> (via C<perl -MDevel::Dwarn ...> for example) and
using C<$obj-E<gt>$::Dwarn()> instead.
-L</default> only supports coderefs, because doing otherwise is usually a
-mistake anyway.
+L</default> only supports coderefs and plain scalars, because passing a hash
+or array reference as a default is almost always incorrect since the value is
+then shared between all objects using that default.
C<lazy_build> is not supported; you are instead encouraged to use the
C<< is => 'lazy' >> option supported by L<Moo> and L<MooseX::AttributeShortcuts>.
-C<auto_deref> is not supported since the author considers it a bad idea.
+C<auto_deref> is not supported since the author considers it a bad idea and
+it has been considered best practice to avoid it for some time.
C<documentation> will show up in a L<Moose> metaclass created from your class
but is otherwise ignored. Then again, L<Moose> ignores it as well, so this
at the end of your class to get an inlined (i.e. not horribly slow)
constructor. Moo does it automatically the first time ->new is called
-on your class.
+on your class. (C<make_immutable> is a no-op in Moo to ease migration.)
An extension L<MooX::late> exists to ease translating Moose packages
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>
+
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>
+
+Bugtracker: L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Moo>
+
+Git repository: L<git://git.shadowcat.co.uk/gitmo/Moo.git>
+
+Git web access: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo/Moo.git>
+
=head1 AUTHOR
mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
haarg - Graham Knop (cpan:HAARG) <haarg@cpan.org>
+mattp - Matt Phillips (cpan:MATTP) <mattp@cpan.org>
+
=head1 COPYRIGHT
Copyright (c) 2010-2011 the Moo L</AUTHOR> and L</CONTRIBUTORS>
=head1 LICENSE
This library is free software and may be distributed under the same terms
-as perl itself.
+as perl itself. See L<http://dev.perl.org/licenses/>.
=cut