use strict;
use warnings;
-our $VERSION = '0.41';
+our $VERSION = '0.51';
our $AUTHORITY = 'cpan:STEVAN';
-use Scalar::Util 'blessed', 'reftype';
-use Carp 'confess';
-use Sub::Name 'subname';
+use Scalar::Util 'blessed';
+use Carp 'confess', 'croak', 'cluck';
use Sub::Exporter;
use Moose::Meta::Class;
use Moose::Meta::TypeConstraint;
-use Moose::Meta::TypeConstraint::Class;
use Moose::Meta::TypeCoercion;
use Moose::Meta::Attribute;
use Moose::Meta::Instance;
my %exports = (
extends => sub {
my $class = $CALLER;
- return subname 'Moose::extends' => sub (@) {
- confess "Must derive at least one class" unless @_;
+ return Class::MOP::subname('Moose::extends' => sub (@) {
+ croak "Must derive at least one class" unless @_;
my @supers = @_;
foreach my $super (@supers) {
# of sync when the classes are being built
my $meta = $class->meta->_fix_metaclass_incompatability(@supers);
$meta->superclasses(@supers);
- };
+ });
},
with => sub {
my $class = $CALLER;
- return subname 'Moose::with' => sub (@) {
+ return Class::MOP::subname('Moose::with' => sub (@) {
Moose::Util::apply_all_roles($class->meta, @_)
- };
+ });
},
has => sub {
my $class = $CALLER;
- return subname 'Moose::has' => sub ($;%) {
+ return Class::MOP::subname('Moose::has' => sub ($;%) {
my $name = shift;
- die 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1;
+ croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1;
my %options = @_;
my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ];
$class->meta->add_attribute( $_, %options ) for @$attrs;
- };
+ });
},
before => sub {
my $class = $CALLER;
- return subname 'Moose::before' => sub (@&) {
- my $code = pop @_;
- my $meta = $class->meta;
- $meta->add_before_method_modifier( $_, $code ) for @_;
- };
+ return Class::MOP::subname('Moose::before' => sub (@&) {
+ Moose::Util::add_method_modifier($class, 'before', \@_);
+ });
},
after => sub {
my $class = $CALLER;
- return subname 'Moose::after' => sub (@&) {
- my $code = pop @_;
- my $meta = $class->meta;
- $meta->add_after_method_modifier( $_, $code ) for @_;
- };
+ return Class::MOP::subname('Moose::after' => sub (@&) {
+ Moose::Util::add_method_modifier($class, 'after', \@_);
+ });
},
around => sub {
my $class = $CALLER;
- return subname 'Moose::around' => sub (@&) {
- my $code = pop @_;
- my $meta = $class->meta;
- $meta->add_around_method_modifier( $_, $code ) for @_;
- };
+ return Class::MOP::subname('Moose::around' => sub (@&) {
+ Moose::Util::add_method_modifier($class, 'around', \@_);
+ });
},
super => sub {
- {
- our %SUPER_SLOT;
- no strict 'refs';
- $SUPER_SLOT{$CALLER} = \*{"${CALLER}::super"};
- }
- return subname 'Moose::super' => sub { };
+ return Class::MOP::subname('Moose::super' => sub {
+ return unless our $SUPER_BODY; $SUPER_BODY->(our @SUPER_ARGS)
+ });
},
override => sub {
my $class = $CALLER;
- return subname 'Moose::override' => sub ($&) {
+ return Class::MOP::subname('Moose::override' => sub ($&) {
my ( $name, $method ) = @_;
$class->meta->add_override_method_modifier( $name => $method );
- };
+ });
},
inner => sub {
- {
- our %INNER_SLOT;
- no strict 'refs';
- $INNER_SLOT{$CALLER} = \*{"${CALLER}::inner"};
- }
- return subname 'Moose::inner' => sub { };
+ return Class::MOP::subname('Moose::inner' => sub {
+ my $pkg = caller();
+ our ( %INNER_BODY, %INNER_ARGS );
+
+ if ( my $body = $INNER_BODY{$pkg} ) {
+ my @args = @{ $INNER_ARGS{$pkg} };
+ local $INNER_ARGS{$pkg};
+ local $INNER_BODY{$pkg};
+ return $body->(@args);
+ } else {
+ return;
+ }
+ });
},
augment => sub {
my $class = $CALLER;
- return subname 'Moose::augment' => sub (@&) {
+ return Class::MOP::subname('Moose::augment' => sub (@&) {
my ( $name, $method ) = @_;
$class->meta->add_augment_method_modifier( $name => $method );
- };
+ });
},
make_immutable => sub {
my $class = $CALLER;
- return subname 'Moose::make_immutable' => sub {
- warn "The make_immutable keyword has been deprecated, " .
- "please go back to __PACKAGE__->meta->make_immutable\n";
+ return Class::MOP::subname('Moose::make_immutable' => sub {
+ cluck "The make_immutable keyword has been deprecated, " .
+ "please go back to __PACKAGE__->meta->make_immutable\n";
$class->meta->make_immutable(@_);
- };
+ });
},
confess => sub {
return \&Carp::confess;
sub _get_caller{
my $offset = 1;
return
- ref $_[1] && defined $_[1]->{into}
- ? $_[1]->{into}
- : ref $_[1] && defined $_[1]->{into_level}
- ? caller($offset + $_[1]->{into_level})
- : caller($offset);
+ (ref $_[1] && defined $_[1]->{into})
+ ? $_[1]->{into}
+ : (ref $_[1] && defined $_[1]->{into_level})
+ ? caller($offset + $_[1]->{into_level})
+ : caller($offset);
}
sub import {
goto $exporter;
}
+
+ # NOTE:
+ # This is for special use by
+ # some modules and stuff, I
+ # dont know if it is sane enough
+ # to document actually.
+ # - SL
+ sub __CURRY_EXPORTS_FOR_CLASS__ {
+ $CALLER = shift;
+ ($CALLER ne 'Moose')
+ || croak "_import_into must be called a function, not a method";
+ ($CALLER->can('meta') && $CALLER->meta->isa('Class::MOP::Class'))
+ || croak "Cannot call _import_into on a package ($CALLER) without a metaclass";
+ return map { $_ => $exports{$_}->() } (@_ ? @_ : keys %exports);
+ }
sub unimport {
no strict 'refs';
# make sure it is from Moose
my ($pkg_name) = Class::MOP::get_code_info($keyword);
- next if $@;
next if $pkg_name ne 'Moose';
# and if it is from Moose then undef the slot
Moose is an extension of the Perl 5 object system.
-=head2 Another object system!?!?
+The main goal of Moose is to make Perl 5 Object Oriented programming
+easier, more consistent and less tedious. With Moose you can to think
+more about what you want to do and less about the mechanics of OOP.
-Yes, I know there has been an explosion recently of new ways to
-build object's in Perl 5, most of them based on inside-out objects
-and other such things. Moose is different because it is not a new
-object system for Perl 5, but instead an extension of the existing
-object system.
-
-Moose is built on top of L<Class::MOP>, which is a metaclass system
-for Perl 5. This means that Moose not only makes building normal
-Perl 5 objects better, but it also provides the power of metaclass
-programming.
-
-=head2 Is this for real? Or is this just an experiment?
-
-Moose is I<based> on the prototypes and experiments I did for the Perl 6
-meta-model. However, Moose is B<NOT> an experiment/prototype; it is for B<real>.
-
-=head2 Is this ready for use in production?
-
-Yes, I believe that it is.
-
-Moose has been used successfully in production environemnts by several people
-and companies (including the one I work for). There are Moose applications
-which have been in production with little or no issue now for well over a year.
-I consider it highly stable and we are commited to keeping it stable.
-
-Of course, in the end, you need to make this call yourself. If you have
-any questions or concerns, please feel free to email me, or even the list
-or just stop by #moose and ask away.
-
-=head2 Is Moose just Perl 6 in Perl 5?
-
-No. While Moose is very much inspired by Perl 6, it is not itself Perl 6.
-Instead, it is an OO system for Perl 5. I built Moose because I was tired of
-writing the same old boring Perl 5 OO code, and drooling over Perl 6 OO. So
-instead of switching to Ruby, I wrote Moose :)
-
-=head2 Wait, I<post> modern, I thought it was just I<modern>?
-
-So I was reading Larry Wall's talk from the 1999 Linux World entitled
-"Perl, the first postmodern computer language" in which he talks about how
-he picked the features for Perl because he thought they were cool and he
-threw out the ones that he thought sucked. This got me thinking about how
-we have done the same thing in Moose. For Moose, we have "borrowed" features
-from Perl 6, CLOS (LISP), Smalltalk, Java, BETA, OCaml, Ruby and more, and
-the bits we didn't like (cause they sucked) we tossed aside. So for this
-reason (and a few others) I have re-dubbed Moose a I<postmodern> object system.
-
-Nuff Said.
+Additionally, Moose is built on top of L<Class::MOP>, which is a
+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 Moose Extensions
The L<MooseX::> namespace is the official place to find Moose extensions.
There are a number of these modules out on CPAN right now the best way to
-find them is to search for MooseX:: on search.cpan.org.
+find them is to search for MooseX:: on search.cpan.org or to look at the
+latest version of L<Task::Moose> which aims to keep an up to date, easily
+installable list of these extensions.
=head1 BUILDING CLASSES WITH MOOSE
You are allowed to B<add> a new C<builder> definition, but you are B<not>
allowed to I<change> one.
+=item I<metaclass>
+
+You are allowed to B<add> a new C<metaclass> definition, but you are
+B<not> allowed to I<change> one.
+
+=item I<traits>
+
+You are allowed to B<add> additional traits to the C<traits> definition.
+These traits will be composed into the attribute, but pre-existing traits
+B<are not> overridden, or removed.
+
=back
=item B<before $name|@names =E<gt> sub { ... }>
The keyword C<inner>, much like C<super>, is a no-op outside of the context of
an C<augment> method. You can think of C<inner> as being the inverse of
C<super>; the details of how C<inner> and C<augment> work is best described in
-the L<Moose::Cookbook::Recipe7>.
+the L<Moose::Cookbook::Recipe6>.
=item B<augment ($name, &sub)>
An C<augment> method, is a way of explicitly saying "I am augmenting this
method from my superclass". Once again, the details of how C<inner> and
-C<augment> work is best described in the L<Moose::Cookbook::Recipe7>.
+C<augment> work is best described in the L<Moose::Cookbook::Recipe6>.
=item B<confess>
=back
+=head1 JUSTIFICATION
+
+In case you are still asking yourself "Why do I need this?", then this
+section is for you. This used to be part of the main DESCRIPTION, but
+I think Moose no longer actually needs justification, so it is included
+(read: buried) here for those who are still not convinced.
+
+=over 4
+
+=item Another object system!?!?
+
+Yes, I know there has been an explosion recently of new ways to
+build objects in Perl 5, most of them based on inside-out objects
+and other such things. Moose is different because it is not a new
+object system for Perl 5, but instead an extension of the existing
+object system.
+
+Moose is built on top of L<Class::MOP>, which is a metaclass system
+for Perl 5. This means that Moose not only makes building normal
+Perl 5 objects better, but it also provides the power of metaclass
+programming.
+
+=item Is this for real? Or is this just an experiment?
+
+Moose is I<based> on the prototypes and experiments I did for the Perl 6
+meta-model. However, Moose is B<NOT> an experiment/prototype; it is for B<real>.
+
+=item Is this ready for use in production?
+
+Yes, I believe that it is.
+
+Moose has been used successfully in production environemnts by several people
+and companies (including the one I work for). There are Moose applications
+which have been in production with little or no issue now for well over two years.
+I consider it highly stable and we are commited to keeping it stable.
+
+Of course, in the end, you need to make this call yourself. If you have
+any questions or concerns, please feel free to email me, or even the list
+or just stop by #moose and ask away.
+
+=item Is Moose just Perl 6 in Perl 5?
+
+No. While Moose is very much inspired by Perl 6, it is not itself Perl 6.
+Instead, it is an OO system for Perl 5. I built Moose because I was tired of
+writing the same old boring Perl 5 OO code, and drooling over Perl 6 OO. So
+instead of switching to Ruby, I wrote Moose :)
+
+=item Wait, I<post> modern, I thought it was just I<modern>?
+
+So I was reading Larry Wall's talk from the 1999 Linux World entitled
+"Perl, the first postmodern computer language" in which he talks about how
+he picked the features for Perl because he thought they were cool and he
+threw out the ones that he thought sucked. This got me thinking about how
+we have done the same thing in Moose. For Moose, we have "borrowed" features
+from Perl 6, CLOS (LISP), Smalltalk, Java, BETA, OCaml, Ruby and more, and
+the bits we didn't like (cause they sucked) we tossed aside. So for this
+reason (and a few others) I have re-dubbed Moose a I<postmodern> object system.
+
+Nuff Said.
+
+=back
+
=head1 ACKNOWLEDGEMENTS
=over 4
=item The Moose mailing list - moose@perl.org
-=item Moose stats on ohloh.net - L<http://www.ohloh.net/projects/5788>
+=item Moose stats on ohloh.net - L<http://www.ohloh.net/projects/moose>
=item Several Moose extension modules in the L<MooseX::> namespace.