X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose.pm;h=32cc4016007869c818eb668363981eefc9a8339c;hb=5185f95455ce476bbe787ea70b551403ee93aada;hp=e67c48bbf8aebc036d76b9783cdc9bb815e541e6;hpb=2f29843cdf35144014ed085f226ccd053adc6067;p=gitmo%2FMoose.git diff --git a/lib/Moose.pm b/lib/Moose.pm index e67c48b..32cc401 100644 --- a/lib/Moose.pm +++ b/lib/Moose.pm @@ -27,7 +27,7 @@ use Moose::Util::TypeConstraints; use Moose::Util (); sub extends { - my $class = caller(); + my $class = shift; croak "Must derive at least one class" unless @_; @@ -50,12 +50,12 @@ sub extends { } sub with { - my $class = caller(); + my $class = shift; Moose::Util::apply_all_roles($class->meta, @_); } sub has { - my $class = caller(); + my $class = shift; my $name = shift; croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1; my %options = @_; @@ -64,17 +64,17 @@ sub has { } sub before { - my $class = caller(); + my $class = shift; Moose::Util::add_method_modifier($class, 'before', \@_); } sub after { - my $class = caller(); + my $class = shift; Moose::Util::add_method_modifier($class, 'after', \@_); } sub around { - my $class = caller(); + my $class = shift; Moose::Util::add_method_modifier($class, 'around', \@_); } @@ -83,7 +83,7 @@ sub super { } sub override { - my $class = caller(); + my $class = shift; my ( $name, $method ) = @_; $class->meta->add_override_method_modifier( $name => $method ); } @@ -103,44 +103,47 @@ sub inner { } sub augment { - my $class = caller(); + my $class = shift; my ( $name, $method ) = @_; $class->meta->add_augment_method_modifier( $name => $method ); } sub make_immutable { - my $class = caller(); + my $class = shift; cluck "The make_immutable keyword has been deprecated, " . "please go back to __PACKAGE__->meta->make_immutable\n"; $class->meta->make_immutable(@_); } my $exporter = Moose::Exporter->build_import_methods( - export => [ - qw( extends with has before after around override augment make_immutable super inner ), + with_caller => [ + qw( extends with has before after around override augment make_immutable ) + ], + as_is => [ + qw( super inner ), \&Carp::confess, \&Scalar::Util::blessed, ], ); -# This exists for backwards compat sub init_meta { - my ( $class, $base_class, $metaclass ) = @_; - - __PACKAGE__->_init_meta( for_class => $class, - object_base_class => $base_class, - metaclass_class => $metaclass, - ); -} + # This used to be called as a function. This hack preserves + # backwards compatibility. + if ( $_[0] ne __PACKAGE__ ) { + return __PACKAGE__->init_meta( + for_class => $_[0], + base_class => $_[1], + metaclass => $_[2], + ); + } -sub _init_meta { shift; my %args = @_; my $class = $args{for_class} - or confess "Cannot call _init_meta without specifying a for_class"; - my $base_class = $args{object_base_class} || 'Moose::Object'; - my $metaclass = $args{metaclass_class} || 'Moose::Meta::Class'; + or confess "Cannot call init_meta without specifying a for_class"; + my $base_class = $args{base_class} || 'Moose::Object'; + my $metaclass = $args{metaclass} || 'Moose::Meta::Class'; confess "The Metaclass $metaclass must be a subclass of Moose::Meta::Class." @@ -180,9 +183,15 @@ sub _init_meta { $meta->superclasses($base_class) unless $meta->superclasses(); + return $meta; } +# This may be used in some older MooseX extensions. +sub _get_caller { + goto &Moose::Exporter::_get_caller; +} + ## make 'em all immutable $_->meta->make_immutable( @@ -259,6 +268,14 @@ metaclass system for Perl 5. This means that Moose not only makes building normal Perl 5 objects better, but it provides the power of metaclass programming as well. +=head2 New to Moose? + +If you're new to Moose, the best place to start is the +L. The recipes on Moose basics will get you up to +speed with many of Moose's features quickly. Once you have an idea of +what Moose can do, you can use the API documentation to get more +detail on features which interest you. + =head2 Moose Extensions The C namespace is the official place to find Moose extensions. @@ -512,16 +529,13 @@ B as the metaclass name. This tells Moose to take the list of C<@role_names> and apply them to the attribute meta-object. This is very similar to the I option, but -allows you to use more than one extension at a time. This too is an advanced -topic, we don't yet have a cookbook for it though. +allows you to use more than one extension at a time. -As with I, the default behavior is to just load C<$role_name>; however, -we also have a way to alias to a shorter name. This will first look to see if -B exists. If it does, Moose -will then check to see if that has the method C, which -should return the actual name of the custom attribute trait. If there is no -C method, it will fall back to using -B as the trait name. +See L for details on how a trait name is +resolved to a class name. + +Also see L for a metaclass trait +example. =back @@ -681,6 +695,36 @@ C anywhere you need to test for an object's class name. =back +=head1 METACLASS TRAITS + +When you use Moose, you can also specify traits which will be applied +to your metaclass: + + use Moose -traits => 'My::Trait'; + +This is very similar to the attribute traits feature. When you do +this, your class's C object will have the specified traits +applied to it. See L for more details. + +=head1 TRAIT NAME RESOLUTION + +By default, when given a trait name, Moose simply tries to load a +class of the same name. If such a class does not exist, it then looks +for for a class matching +B. The C<$type> +variable here will be one of B or B, depending on +what the trait is being applied to. + +If a class with this long name exists, Moose checks to see if it has +the method C. This method is expected to +return the I class name of the trait. If there is no +C method, it will fall back to using +B as the trait name. + +If all this is confusing, take a look at +L, which demonstrates how to create an +attribute trait. + =head1 UNIMPORTING FUNCTIONS =head2 B @@ -704,45 +748,72 @@ to work. Here is an example: =head1 EXTENDING AND EMBEDDING MOOSE -Moose also offers some options for extending or embedding it into your own -framework. The basic premise is to have something that sets up your class' -metaclass and export the moose declarators (C, C, C,...). -Here is an example: +Moose also offers some options for extending or embedding it into your +own framework. There are several things you might want to do as part +of such a framework. First, you probably want to export Moose's sugar +functions (C, C, etc) for users of the +framework. Second, you may want to provide additional sugar of your +own. Third, you may want to provide your own object base class instead +of L, and/or your own metaclass class instead of +L. - package MyFramework; - use Moose; +The exporting needs can be asily satisfied by using +L, which is what C itself uses for +exporting. L lets you "export like Moose". + +If you define an C method in a module that uses +L, then this method will be called I +C's own C. This gives you a chance to provide an +alternate object base class or metaclass class. - sub import { - my $CALLER = caller(); +Here is a simple example: + + package MyFramework; - strict->import; - warnings->import; + use strict; + use warnings; - # we should never export to main - return if $CALLER eq 'main'; - Moose::init_meta( $CALLER, 'MyFramework::Base' ); - Moose->import({into => $CALLER}); + use Moose (); # no need to get Moose's exports + use Moose::Exporter; - # Do my custom framework stuff + Moose::Exporter->build_import_methods( also => 'Moose' ); - return 1; + sub init_meta { + shift; + return Moose->init_meta( @_, base_class => 'MyFramework::Base' ); } -=head2 B +In this example, any class that includes C will get +all of C's sugar functions, and will have their superclass +set to C. -Moose's C method supports the L form of C<{into =E $pkg}> -and C<{into_level =E 1}> +Additionally, that class can include C to unimport + +=head2 B<< Moose->init_meta(for_class => $class, base_class => $baseclass, metaclass => $metaclass) >> -=head2 B +The C method sets up the metaclass object for the class +specified by C. This method injects a a C accessor +into the class so you can get at this object. It also sets the class's +superclass to C, with L as the default. -Moose does some boot strapping: it creates a metaclass object for your class, -and then injects a C accessor into your class to retrieve it. Then it -sets your baseclass to Moose::Object or the value you pass in unless you already -have one. This is all done via C which takes the name of your class -and optionally a baseclass and a metaclass as arguments. +You can specify an alternate metaclass with the C parameter. For more detail on this topic, see L. +This method used to be documented as a function which accepted +positional parameters. This calling style will still work for +backwards compatibility, but is deprecated. + +=head2 B + +Moose's C method supports the L form of C<{into =E $pkg}> +and C<{into_level =E 1}>. + +B: Doing this is more or less deprecated. Use L +instead, which lets you stack multiple C-alike modules +sanely. It handles getting the exported functions into the right place +for you. + =head1 CAVEATS =over 4