X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose.pm;h=43432c2d70c7c8b1bbc359f2f2e2284225134761;hb=7176be9beca87b047f077bd71019e05b42e18713;hp=9b0fb44f8aa57983a59592a0c331c32fb059271c;hpb=5cfe38055a8397c20063f7e76c29f0734f86890b;p=gitmo%2FMoose.git diff --git a/lib/Moose.pm b/lib/Moose.pm index 9b0fb44..43432c2 100644 --- a/lib/Moose.pm +++ b/lib/Moose.pm @@ -4,15 +4,18 @@ package Moose; use strict; use warnings; -our $VERSION = '0.55'; +use 5.008; + +our $VERSION = '0.63'; +$VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; use Scalar::Util 'blessed'; use Carp 'confess', 'croak', 'cluck'; -use Sub::Exporter; +use Moose::Exporter; -use Class::MOP 0.64; +use Class::MOP 0.72; use Moose::Meta::Class; use Moose::Meta::TypeConstraint; @@ -20,270 +23,254 @@ use Moose::Meta::TypeCoercion; use Moose::Meta::Attribute; use Moose::Meta::Instance; +use Moose::Object; + use Moose::Meta::Role; +use Moose::Meta::Role::Composite; +use Moose::Meta::Role::Application; +use Moose::Meta::Role::Application::RoleSummation; +use Moose::Meta::Role::Application::ToClass; +use Moose::Meta::Role::Application::ToRole; +use Moose::Meta::Role::Application::ToInstance; -use Moose::Object; use Moose::Util::TypeConstraints; use Moose::Util (); -{ - my $CALLER; - - sub init_meta { - my ( $class, $base_class, $metaclass ) = @_; - $base_class = 'Moose::Object' unless defined $base_class; - $metaclass = 'Moose::Meta::Class' unless defined $metaclass; - - confess - "The Metaclass $metaclass must be a subclass of Moose::Meta::Class." - unless $metaclass->isa('Moose::Meta::Class'); - - # make a subtype for each Moose class - class_type($class) - unless find_type_constraint($class); - - my $meta; - if ( $class->can('meta') ) { - # NOTE: - # this is the case where the metaclass pragma - # was used before the 'use Moose' statement to - # override a specific class - $meta = $class->meta(); - ( blessed($meta) && $meta->isa('Moose::Meta::Class') ) - || confess "You already have a &meta function, but it does not return a Moose::Meta::Class"; - } - else { - # NOTE: - # this is broken currently, we actually need - # to allow the possiblity of an inherited - # meta, which will not be visible until the - # user 'extends' first. This needs to have - # more intelligence to it - $meta = $metaclass->initialize($class); - $meta->add_method( - 'meta' => sub { - # re-initialize so it inherits properly - $metaclass->initialize( blessed( $_[0] ) || $_[0] ); - } - ); - } +sub throw_error { + # FIXME This + shift; + goto \&confess +} + +sub extends { + my $class = shift; - # make sure they inherit from Moose::Object - $meta->superclasses($base_class) - unless $meta->superclasses(); - - return $meta; + croak "Must derive at least one class" unless @_; + + my @supers = @_; + foreach my $super (@supers) { + Class::MOP::load_class($super); + croak "You cannot inherit from a Moose Role ($super)" + if $super->can('meta') && + blessed $super->meta && + $super->meta->isa('Moose::Meta::Role') } - my %exports = ( - extends => sub { - my $class = $CALLER; - return Class::MOP::subname('Moose::extends' => sub (@) { - croak "Must derive at least one class" unless @_; - - my @supers = @_; - foreach my $super (@supers) { - Class::MOP::load_class($super); - croak "You cannot inherit from a Moose Role ($super)" - if $super->can('meta') && - blessed $super->meta && - $super->meta->isa('Moose::Meta::Role') - } + # this checks the metaclass to make sure + # it is correct, sometimes it can get out + # of sync when the classes are being built + my $meta = Moose::Meta::Class->initialize($class); + $meta->superclasses(@supers); +} - # this checks the metaclass to make sure - # it is correct, sometimes it can get out - # 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 Class::MOP::subname('Moose::with' => sub (@) { - Moose::Util::apply_all_roles($class->meta, @_) - }); - }, - has => sub { - my $class = $CALLER; - return Class::MOP::subname('Moose::has' => sub ($;%) { - my $name = shift; - 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 Class::MOP::subname('Moose::before' => sub (@&) { - Moose::Util::add_method_modifier($class, 'before', \@_); - }); - }, - after => sub { - my $class = $CALLER; - return Class::MOP::subname('Moose::after' => sub (@&) { - Moose::Util::add_method_modifier($class, 'after', \@_); - }); - }, - around => sub { - my $class = $CALLER; - return Class::MOP::subname('Moose::around' => sub (@&) { - Moose::Util::add_method_modifier($class, 'around', \@_); - }); - }, - 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 Class::MOP::subname('Moose::override' => sub ($&) { - my ( $name, $method ) = @_; - $class->meta->add_override_method_modifier( $name => $method ); - }); - }, - 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 Class::MOP::subname('Moose::augment' => sub (@&) { - my ( $name, $method ) = @_; - $class->meta->add_augment_method_modifier( $name => $method ); - }); - }, - make_immutable => sub { - my $class = $CALLER; - 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; - }, - blessed => sub { - return \&Scalar::Util::blessed; - }, - ); - - my $exporter = Sub::Exporter::build_exporter( - { - exports => \%exports, - groups => { default => [':all'] } - } - ); - - # 1 extra level because it's called by import so there's a layer of indirection - 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); - } +sub with { + my $class = shift; + Moose::Util::apply_all_roles(Class::MOP::Class->initialize($class), @_); +} - sub import { - $CALLER = _get_caller(@_); +sub has { + my $class = shift; + my $name = shift; + croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1; + my %options = @_; + my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ]; + Class::MOP::Class->initialize($class)->add_attribute( $_, %options ) for @$attrs; +} - # this works because both pragmas set $^H (see perldoc perlvar) - # which affects the current compilation - i.e. the file who use'd - # us - which is why we don't need to do anything special to make - # it affect that file rather than this one (which is already compiled) +sub before { + my $class = shift; + Moose::Util::add_method_modifier($class, 'before', \@_); +} + +sub after { + my $class = shift; + Moose::Util::add_method_modifier($class, 'after', \@_); +} - strict->import; - warnings->import; +sub around { + my $class = shift; + Moose::Util::add_method_modifier($class, 'around', \@_); +} - # we should never export to main - return if $CALLER eq 'main'; +sub super { + return unless our $SUPER_BODY; $SUPER_BODY->(our @SUPER_ARGS); +} - init_meta( $CALLER, 'Moose::Object' ); +sub override { + my $class = shift; + my ( $name, $method ) = @_; + Class::MOP::Class->initialize($class)->add_override_method_modifier( $name => $method ); +} - goto $exporter; +sub inner { + 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; } - - # 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 augment { + my $class = shift; + my ( $name, $method ) = @_; + Class::MOP::Class->initialize($class)->add_augment_method_modifier( $name => $method ); +} + +Moose::Exporter->setup_import_methods( + with_caller => [ + qw( extends with has before after around override augment) + ], + as_is => [ + qw( super inner ), + \&Carp::confess, + \&Scalar::Util::blessed, + ], +); + +sub init_meta { + # 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 unimport { - no strict 'refs'; - my $class = _get_caller(@_); + shift; + my %args = @_; + + my $class = $args{for_class} + or Moose->throw_error("Cannot call init_meta without specifying a for_class"); + my $base_class = $args{base_class} || 'Moose::Object'; + my $metaclass = $args{metaclass} || 'Moose::Meta::Class'; + + Moose->throw_error("The Metaclass $metaclass must be a subclass of Moose::Meta::Class.") + unless $metaclass->isa('Moose::Meta::Class'); + + # make a subtype for each Moose class + class_type($class) + unless find_type_constraint($class); + + my $meta; + + if ( $meta = Class::MOP::get_metaclass_by_name($class) ) { + unless ( $meta->isa("Moose::Meta::Class") ) { + Moose->throw_error("$class already has a metaclass, but it does not inherit $metaclass ($meta)"); + } + } else { + # no metaclass, no 'meta' method - # loop through the exports ... - foreach my $name ( keys %exports ) { + # now we check whether our ancestors have metaclass, and if so borrow that + my ( undef, @isa ) = @{ $class->mro::get_linear_isa }; - # if we find one ... - if ( defined &{ $class . '::' . $name } ) { - my $keyword = \&{ $class . '::' . $name }; + foreach my $ancestor ( @isa ) { + my $ancestor_meta = Class::MOP::get_metaclass_by_name($ancestor) || next; - # make sure it is from Moose - my ($pkg_name) = Class::MOP::get_code_info($keyword); - next if $pkg_name ne 'Moose'; + my $ancestor_meta_class = ($ancestor_meta->is_immutable + ? $ancestor_meta->get_mutable_metaclass_name + : ref($ancestor_meta)); - # and if it is from Moose then undef the slot - delete ${ $class . '::' }{$name}; + # if we have an ancestor metaclass that inherits $metaclass, we use + # that. This is like _fix_metaclass_incompatibility, but we can do it now. + + # the case of having an ancestry is not very common, but arises in + # e.g. Reaction + unless ( $metaclass->isa( $ancestor_meta_class ) ) { + if ( $ancestor_meta_class->isa($metaclass) ) { + $metaclass = $ancestor_meta_class; + } } } + + $meta = $metaclass->initialize($class); + } + + if ( $class->can('meta') ) { + # check 'meta' method + + # it may be inherited + + # NOTE: + # this is the case where the metaclass pragma + # was used before the 'use Moose' statement to + # override a specific class + my $method_meta = $class->meta; + + ( blessed($method_meta) && $method_meta->isa('Moose::Meta::Class') ) + || Moose->throw_error("$class already has a &meta function, but it does not return a Moose::Meta::Class ($meta)"); + + $meta = $method_meta; + } + + unless ( $meta->has_method("meta") ) { # don't overwrite + # also check for inherited non moose 'meta' method? + # FIXME also skip this if the user requested by passing an option + $meta->add_method( + 'meta' => sub { + # re-initialize so it inherits properly + $metaclass->initialize( ref($_[0]) || $_[0] ); + } + ); } + # make sure they inherit from Moose::Object + $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( - inline_constructor => 0, - inline_accessors => 1, # these are Class::MOP accessors, so they need inlining - ) - for ( - 'Moose::Meta::Attribute', - 'Moose::Meta::Class', - 'Moose::Meta::Instance', - - 'Moose::Meta::TypeConstraint', - 'Moose::Meta::TypeConstraint::Union', - 'Moose::Meta::TypeConstraint::Parameterized', - 'Moose::Meta::TypeCoercion', - - 'Moose::Meta::Method', - 'Moose::Meta::Method::Accessor', - 'Moose::Meta::Method::Constructor', - 'Moose::Meta::Method::Destructor', - 'Moose::Meta::Method::Overriden', - - 'Moose::Meta::Role', - 'Moose::Meta::Role::Method', - 'Moose::Meta::Role::Method::Required', - ); +$_->make_immutable( + inline_constructor => 1, + constructor_name => "_new", + # these are Class::MOP accessors, so they need inlining + inline_accessors => 1 + ) for grep { $_->is_mutable } + map { $_->meta } + qw( + Moose::Meta::Attribute + Moose::Meta::Class + Moose::Meta::Instance + + Moose::Meta::TypeCoercion + Moose::Meta::TypeCoercion::Union + + Moose::Meta::Method + Moose::Meta::Method::Accessor + Moose::Meta::Method::Constructor + Moose::Meta::Method::Destructor + Moose::Meta::Method::Overriden + Moose::Meta::Method::Augmented + + Moose::Meta::Role + Moose::Meta::Role::Method + Moose::Meta::Role::Method::Required + + Moose::Meta::Role::Composite + + Moose::Meta::Role::Application + Moose::Meta::Role::Application::RoleSummation + Moose::Meta::Role::Application::ToClass + Moose::Meta::Role::Application::ToRole + Moose::Meta::Role::Application::ToInstance +); 1; @@ -327,12 +314,23 @@ Moose is an extension of the Perl 5 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. +more about what you want to do and less about the mechanics of OOP. -Additionally, Moose is built on top of L, 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. +Additionally, Moose is built on top of L, 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 New to Moose? + +If you're new to Moose, the best place to start is the L +docs, followed by the L. The intro will show you what +Moose is, and how it makes Perl 5 OO better. + +The cookbook 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 @@ -391,12 +389,13 @@ superclasses still properly inherit from L. This will apply a given set of C<@roles> to the local class. -=item B %options> +=item B %options> -This will install an attribute of a given C<$name> into the current class. -The C<%options> are the same as those provided by -L, in addition to the list below which are provided -by Moose (L to be more specific): +This will install an attribute of a given C<$name> into the current class. If +the first parameter is an array reference, it will create an attribute for +every C<$name> in the list. The C<%options> are the same as those provided by +L, in addition to the list below which are provided by +Moose (L to be more specific): =over 4 @@ -406,10 +405,12 @@ The I option accepts either I (for read/write) or I (for read only). These will create either a read/write accessor or a read-only accessor respectively, using the same name as the C<$name> of the attribute. -If you need more control over how your accessors are named, you can use the -I, I and I options inherited from -L, however if you use those, you won't need the I -option. +If you need more control over how your accessors are named, you can +use the L, +L and +L options inherited from +L, however if you use those, you won't need the +I option. =item I $type_name> @@ -460,7 +461,11 @@ The I option is a CODE reference which will be called after the value o the attribute is set. The CODE ref will be passed the instance itself, the updated value and the attribute meta-object (this is for more advanced fiddling and can typically be ignored). You B have a trigger on a read-only -attribute. +attribute. + +B Triggers will only fire when you B to the attribute, +either in the constructor, or using the writer. Default and built values will +B cause the trigger to be fired. =item I ARRAY | HASH | REGEXP | ROLE | CODE> @@ -587,22 +592,66 @@ 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. + +See L for details on how a trait name is +resolved to a class name. + +Also see L for a metaclass trait +example. + +=item I => Str + +The value of this key is the name of the method that will be called to +obtain the value used to initialize the attribute. See the L +for more information. + +=item I => SCALAR | CODE + +The value of this key is the default value which will initialize the attribute. + +NOTE: If the value is a simple scalar (string or number), then it can +be just passed as is. However, if you wish to initialize it with a +HASH or ARRAY ref, then you need to wrap that inside a CODE reference. +See the L for more +information. + +=item I => Str + +This may be a method name (referring to a method on the class with +this attribute) or a CODE ref. The initializer is used to set the +attribute value on an instance when the attribute is set during +instance initialization (but not when the value is being assigned +to). See the L for more +information. + +=item I => Str + +Allows you to clear the value, see the L for more +information. + +=item I => Str + +Basic test to see if a value has been set in the attribute, see the +L for more +information. + +=item I => (0|1) + +Automatically define lazy => 1 as well as builder => "_build_$attr", clearer => +"clear_$attr', predicate => 'has_$attr' unless they are already defined. -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. =back =item B %options> -This is variation on the normal attibute creator C which allows you to +This is variation on the normal attribute creator C which allows you to clone and extend an attribute from a superclass or from a role. Here is an example of the superclass usage: @@ -681,7 +730,7 @@ You I allowed to change the type without restriction. It is recommended that you use this freedom with caution. We used to only allow for extension only if the type was a subtype of the parent's type, but we felt that was too restrictive and is better left as a -policy descision. +policy decision. =item I @@ -756,6 +805,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 @@ -779,42 +858,89 @@ 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: - - package MyFramework; - use Moose; +To learn more about extending Moose, we recommend checking out the +"Extending" recipes in the L, starting with +L, which provides an overview of +all the different ways you might extend Moose. - sub import { - my $CALLER = caller(); +=head2 B<< Moose->init_meta(for_class => $class, base_class => $baseclass, metaclass => $metaclass) >> - strict->import; - warnings->import; +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. - # we should never export to main - return if $CALLER eq 'main'; - Moose::init_meta( $CALLER, 'MyFramework::Base' ); - Moose->import({into => $CALLER}); +You can specify an alternate metaclass with the C parameter. - # Do my custom framework stuff +For more detail on this topic, see L. - return 1; - } +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}> +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. + +=head2 B + +An alias for C, used by internally by Moose. + +=head1 METACLASS COMPATIBILITY AND MOOSE + +Metaclass compatibility is a thorny subject. You should start by +reading the "About Metaclass compatibility" section in the +C docs. + +Moose will attempt to resolve a few cases of metaclass incompatibility +when you set the superclasses for a class, unlike C, which +simply dies if the metaclasses are incompatible. + +In actuality, Moose fixes incompatibility for I of a class's +metaclasses, not just the class metaclass. That includes the instance +metaclass, attribute metaclass, as well as its constructor class and +destructor class. However, for simplicity this discussion will just +refer to "metaclass", meaning the class metaclass, most of the time. -=head2 B +Moose has two algorithms for fixing metaclass incompatibility. -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. +The first algorithm is very simple. If all the metaclass for the +parent is a I of the child's metaclass, then we simply +replace the child's metaclass with the parent's. + +The second algorithm is more complicated. It tries to determine if the +metaclasses only "differ by roles". This means that the parent and +child's metaclass share a common ancestor in their respective +hierarchies, and that the subclasses under the common ancestor are +only different because of role applications. This case is actually +fairly common when you mix and match various C modules, +many of which apply roles to the metaclass. + +If the parent and child do differ by roles, Moose replaces the +metaclass in the child with a newly created metaclass. This metaclass +is a subclass of the parent's metaclass, does all of the roles that +the child's metaclass did before being replaced. Effectively, this +means the new metaclass does all of the roles done by both the +parent's and child's original metaclasses. + +Ultimately, this is all transparent to you except in the case of an +unresolvable conflict. + +=head2 The MooseX:: namespace + +Generally if you're writing an extension I Moose itself you'll want +to put your extension in the C namespace. This namespace is +specifically for extensions that make Moose better or different in some +fundamental way. It is traditionally B for a package that just happens +to use Moose. This namespace follows from the examples of the C +and C namespaces that perform the same function for C and C +respectively. =head1 CAVEATS @@ -836,75 +962,6 @@ two features separate (yet interoperable) actually makes them easy to use, since their behavior is then easier to predict. Time will tell whether I am right or not (UPDATE: so far so good). -=item * - -It is important to note that we currently have no simple way of combining -multiple extended versions of Moose (see L above), -and that in many cases they will conflict with one another. We are working on -developing a way around this issue, but in the meantime, you have been warned. - -=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, 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 on the prototypes and experiments I did for the Perl 6 -meta-model. However, Moose is B an experiment/prototype; it is for B. - -=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 modern, I thought it was just I? - -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 object system. - -Nuff Said. - =back =head1 ACKNOWLEDGEMENTS @@ -1000,9 +1057,26 @@ either email the mailing list or join us on irc at #moose to discuss. =head1 AUTHOR -Stevan Little Estevan@iinteractive.comE +Moose is an open project, there are at this point dozens of people who have +contributed, and can contribute. If you have added anything to the Moose +project you have a commit bit on this file and can add your name to the list. + +=head2 CABAL + +However there are only a few people with the rights to release a new version +of Moose. The Moose Cabal are the people to go to with questions regarding +the wider purview of Moose, and help out maintaining not just the code +but the community as well. + +Stevan (stevan) Little Estevan@iinteractive.comE + +Yuval (nothingmuch) Kogman + +Shawn (sartak) Moore + +Dave (autarch) Rolsky Eautarch@urth.orgE -B +=head2 OTHER CONTRIBUTORS Aankhen @@ -1032,8 +1106,6 @@ Scott (konobi) McWhirter Shlomi (rindolf) Fish -Yuval (nothingmuch) Kogman - Chris (perigrin) Prather Wallace (wreis) Reis @@ -1044,8 +1116,6 @@ Piotr (dexter) Roszatycki Sam (mugwump) Vilain -Shawn (sartak) Moore - ... and many other #moose folks =head1 COPYRIGHT AND LICENSE