X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoo.pm;h=bcc4b71607f251ecd43c2280c060abd3f544bfaa;hb=8dee08c10f9b63372dff89d38b37b175cdda4489;hp=e947e31631f534625fc1f13813f6f7d68335c489;hpb=fa93bfb29cca2d07be28c8459e1626a59a80245c;p=gitmo%2FMoo.git diff --git a/lib/Moo.pm b/lib/Moo.pm index e947e31..bcc4b71 100644 --- a/lib/Moo.pm +++ b/lib/Moo.pm @@ -5,7 +5,7 @@ use Moo::_Utils; use B 'perlstring'; use Sub::Defer (); -our $VERSION = '1.000007'; # 1.0.7 +our $VERSION = '1.002000'; # 1.2.0 $VERSION = eval $VERSION; require Moo::sification; @@ -93,6 +93,9 @@ sub _set_superclasses { 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($_), @_ @@ -132,32 +135,27 @@ sub _accessor_maker_for { } sub _constructor_maker_for { - my ($class, $target, $select_super) = @_; + my ($class, $target) = @_; return unless $MAKERS{$target}; $MAKERS{$target}{constructor} ||= do { require Method::Generate::Constructor; require Sub::Defer; my ($moo_constructor, $con); - if ($select_super && $MAKERS{$select_super}) { - $moo_constructor = 1; - $con = $MAKERS{$select_super}{constructor}; - } else { - my $t_new = $target->can('new'); - if ($t_new) { - if ($t_new == Moo::Object->can('new')) { + my $t_new = $target->can('new'); + if ($t_new) { + if ($t_new == Moo::Object->can('new')) { + $moo_constructor = 1; + } elsif (my $defer_target = (Sub::Defer::defer_info($t_new)||[])->[0]) { + my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/); + if ($MAKERS{$pkg}) { $moo_constructor = 1; - } elsif (my $defer_target = (Sub::Defer::defer_info($t_new)||[])->[0]) { - my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/); - if ($MAKERS{$pkg}) { - $moo_constructor = 1; - $con = $MAKERS{$pkg}{constructor}; - } + $con = $MAKERS{$pkg}{constructor}; } - } else { - $moo_constructor = 1; # no other constructor, make a Moo one } - }; + } else { + $moo_constructor = 1; # no other constructor, make a Moo one + } ($con ? ref($con) : 'Method::Generate::Constructor') ->new( package => $target, @@ -165,7 +163,7 @@ sub _constructor_maker_for { 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" @@ -188,7 +186,7 @@ sub _constructor_maker_for { =head1 NAME -Moo - Minimalist Object Orientation (with Moose compatiblity) +Moo - Minimalist Object Orientation (with Moose compatibility) =head1 SYNOPSIS @@ -212,7 +210,7 @@ Moo - Minimalist Object Orientation (with Moose compatiblity) isa => sub { die "Only SWEET-TREATZ supported!" unless $_[0] eq 'SWEET-TREATZ' }, -); + ); has pounds => ( is => 'rw', @@ -281,6 +279,10 @@ metaclasses for your L and L packages, so you should be able to use them in L code without anybody ever noticing you aren't using L everywhere. +L will also create L for +classes and roles, so that C<< isa => 'MyClass' >> and C<< isa => 'MyRole' >> +work the same as for L classes and roles. + Extending a L class or consuming a L will also work. So will extending a L class or consuming a L - but note @@ -358,6 +360,13 @@ passed to the constructor. 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 method. +It will receive the same arguments as C, and should return a list +of arguments to pass to the parent class constructor. + =head2 BUILD Define a C method on your class and the constructor will automatically @@ -415,6 +424,21 @@ class. An error will be raised if these roles have conflicting methods. 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 are as follows: =over 2 @@ -430,7 +454,9 @@ C generates a reader like C, but also sets C to 1 and C to C<_build_${attribute_name}> to allow on-demand generated attributes. This feature was my attempt to fix my incompetence when originally designing C, and is also implemented by -L. +L. There is, however, nothing to stop you +using C and C yourself with C or C - it's just that +this isn't generally a good idea so we don't provide a shortcut for it. C generates a reader like C, but also sets C to C<_set_${attribute_name}> for attributes that are designed to be written @@ -450,6 +476,9 @@ one should do 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 Since L does B run the C check before C if a coercion @@ -509,11 +538,11 @@ Takes a hashref un => 'one', } -=item * trigger +=item * C Takes a coderef which will get called any time the attribute is set. This -includes the constructor. Coderef will be invoked against the object with the -new value as an argument. +includes the constructor, but not default or built values. Coderef will be +invoked against the object with the new value as an argument. If you set this to just C<1>, it generates a trigger which calls the C<_trigger_${attr_name}> method on C<$self>. This feature comes from @@ -531,6 +560,10 @@ to populate an attribute if no value is supplied to the constructor - or 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. @@ -543,7 +576,7 @@ Takes a method name which will return true if an attribute has a value. If you set this to just C<1>, the predicate is automatically named C 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. =item * C @@ -610,6 +643,13 @@ common use of this is to make an underscored attribute have a non-underscored initialization name. C means that passing the value in on instantiation is ignored. +=item * C + +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 @@ -687,7 +727,7 @@ API will encourage the use of other type systems as well, since it's probably the weakest part of Moose design-wise. C 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 or +bad idea and Moose best practices recommend avoiding it. Meanwhile C or C are more likely to be able to fulfill your needs. There is no meta object. If you need this level of complexity you wanted @@ -718,13 +758,15 @@ The C method is not provided by default. The author suggests loading L into C (via C for example) and using C<$obj-E$::Dwarn()> instead. -L only supports coderefs, because doing otherwise is usually a -mistake anyway. +L 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 is not supported; you are instead encouraged to use the C<< is => 'lazy' >> option supported by L and L. -C is not supported since the author considers it a bad idea. +C 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 will show up in a L metaclass created from your class but is otherwise ignored. Then again, L ignores it as well, so this @@ -770,7 +812,7 @@ Finally, Moose requires you to call 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 is a no-op in Moo to ease migration.) An extension L exists to ease translating Moose packages to Moo by providing a more Moose-like interface. @@ -779,8 +821,18 @@ to Moo by providing a more Moose-like interface. Users' IRC: #moose on irc.perl.org +=for html (click for instant chatroom login) + Development and contribution IRC: #web-simple on irc.perl.org +=for html (click for instant chatroom login) + +Bugtracker: L + +Git repository: L + +Git web access: L + =head1 AUTHOR mst - Matt S. Trout (cpan:MSTROUT) @@ -811,6 +863,10 @@ ilmari - Dagfinn Ilmari Mannsåker (cpan:ILMARI) tobyink - Toby Inkster (cpan:TOBYINK) +haarg - Graham Knop (cpan:HAARG) + +mattp - Matt Phillips (cpan:MATTP) + =head1 COPYRIGHT Copyright (c) 2010-2011 the Moo L and L @@ -819,6 +875,6 @@ as listed above. =head1 LICENSE This library is free software and may be distributed under the same terms -as perl itself. +as perl itself. See L. =cut