X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoo.pm;h=6bf3fc007ea14c150d47e872f53bc46a1b38c506;hb=349ea75bb916f05ad325841b500e1fd0a9d5f2e4;hp=2f7db1ac6d0effbdbb4560842a9aa69f9c226800;hpb=16382e05b20e87b0bc13bfcebc1554f5ca687158;p=gitmo%2FMoo.git diff --git a/lib/Moo.pm b/lib/Moo.pm index 2f7db1a..6bf3fc0 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.000008'; # 1.0.8 +our $VERSION = '1.003000'; $VERSION = eval $VERSION; require Moo::sification; @@ -22,7 +22,7 @@ sub import { 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} ||= {}; @@ -37,12 +37,18 @@ sub import { $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) @@ -93,6 +99,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($_), @_ @@ -165,7 +174,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 +197,7 @@ sub _constructor_maker_for { =head1 NAME -Moo - Minimalist Object Orientation (with Moose compatiblity) +Moo - Minimalist Object Orientation (with Moose compatibility) =head1 SYNOPSIS @@ -281,6 +290,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 @@ -308,6 +321,15 @@ to your code before Moose is loaded, but bear in mind that this switch is 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 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 will behave slightly differently: they will +reject attempts to call them with the incorrect number of parameters. + =head1 MOO VERSUS ANY::MOOSE L will load L normally, and L in a program using @@ -358,6 +380,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 +444,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 @@ -452,6 +496,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 @@ -482,7 +529,7 @@ Takes a coderef which is meant to coerce the attribute. The basic idea is to do something like the following: coerce => sub { - $_[0] + 1 unless $_[0] % 2 + $_[0] % 2 ? $_[0] : $_[0] + 1 }, Note that L will always fire your coercion: this is to permit @@ -533,6 +580,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. @@ -545,7 +596,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 @@ -612,6 +663,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 @@ -689,7 +747,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 @@ -720,13 +778,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 @@ -772,7 +832,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. @@ -781,8 +841,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) @@ -815,6 +885,8 @@ 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 @@ -823,6 +895,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