-
package Moose;
-
use strict;
use warnings;
use 5.008;
-our $VERSION = '0.76';
+our $VERSION = '0.94';
$VERSION = eval $VERSION;
our $AUTHORITY = 'cpan:STEVAN';
use Moose::Exporter;
-use Class::MOP 0.82_01;
+use Class::MOP 0.94;
use Moose::Meta::Class;
use Moose::Meta::TypeConstraint;
use Moose::Util::TypeConstraints;
use Moose::Util ();
-sub _caller_info {
- my $level = @_ ? ($_[0] + 1) : 2;
- my %info;
- @info{qw(package file line)} = caller($level);
- return \%info;
-}
+use Moose::Meta::Attribute::Native;
sub throw_error {
# FIXME This
}
sub extends {
- my $class = shift;
+ my $meta = shift;
Moose->throw_error("Must derive at least one class") unless @_;
# this checks the metaclass to make sure
# it is correct, sometimes it can get out
# of sync when the classes are being built
- Moose::Meta::Class->initialize($class)->superclasses(@_);
+ $meta->superclasses(@_);
}
sub with {
- my $class = shift;
- Moose::Util::apply_all_roles(Class::MOP::Class->initialize($class), @_);
+ Moose::Util::apply_all_roles(shift, @_);
}
sub has {
- my $class = shift;
- my $name = shift;
+ my $meta = shift;
+ my $name = shift;
Moose->throw_error('Usage: has \'name\' => ( key => value, ... )')
- if @_ == 1;
+ if @_ % 2 == 1;
- my %options = ( definition_context => _caller_info(), @_ );
+ my %options = ( definition_context => Moose::Util::_caller_info(), @_ );
my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ];
- Class::MOP::Class->initialize($class)->add_attribute( $_, %options ) for @$attrs;
+ $meta->add_attribute( $_, %options ) for @$attrs;
}
sub before {
- my $class = shift;
- Moose::Util::add_method_modifier($class, 'before', \@_);
+ Moose::Util::add_method_modifier(shift, 'before', \@_);
}
sub after {
- my $class = shift;
- Moose::Util::add_method_modifier($class, 'after', \@_);
+ Moose::Util::add_method_modifier(shift, 'after', \@_);
}
sub around {
- my $class = shift;
- Moose::Util::add_method_modifier($class, 'around', \@_);
+ Moose::Util::add_method_modifier(shift, 'around', \@_);
}
our $SUPER_PACKAGE;
}
sub override {
- my $class = shift;
+ my $meta = shift;
my ( $name, $method ) = @_;
- Class::MOP::Class->initialize($class)->add_override_method_modifier( $name => $method );
+ $meta->add_override_method_modifier( $name => $method );
}
sub inner {
}
sub augment {
- my $class = shift;
+ my $meta = shift;
my ( $name, $method ) = @_;
- Class::MOP::Class->initialize($class)->add_augment_method_modifier( $name => $method );
+ $meta->add_augment_method_modifier( $name => $method );
}
Moose::Exporter->setup_import_methods(
- with_caller => [
- qw( extends with has before after around override augment)
+ with_meta => [
+ qw( extends with has before after around override augment )
],
as_is => [
qw( super inner ),
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)");
+ my $error_message = "$class already has a metaclass, but it does not inherit $metaclass ($meta).";
+ if ( $meta->isa('Moose::Meta::Role') ) {
+ Moose->throw_error($error_message . ' You cannot make the same thing a role and a class. Remove either Moose or Moose::Role.');
+ } else {
+ Moose->throw_error($error_message);
+ }
}
} else {
# no metaclass, no 'meta' method
my $ancestor_meta = Class::MOP::get_metaclass_by_name($ancestor) || next;
my $ancestor_meta_class = ($ancestor_meta->is_immutable
- ? $ancestor_meta->get_mutable_metaclass_name
+ ? $ancestor_meta->_get_mutable_metaclass_name
: ref($ancestor_meta));
# if we have an ancestor metaclass that inherits $metaclass, we use
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)");
+ || Moose->throw_error("$class already has a &meta function, but it does not return a Moose::Meta::Class ($method_meta)");
$meta = $method_meta;
}
Moose::Meta::Method::Augmented
Moose::Meta::Role
+ Moose::Meta::Role::Attribute
Moose::Meta::Role::Method
Moose::Meta::Role::Method::Required
+ Moose::Meta::Role::Method::Conflicting
Moose::Meta::Role::Composite
Moose::Meta::Role::Application::ToInstance
);
+Moose::Meta::Mixin::AttributeCore->meta->make_immutable(
+ inline_constructor => 0,
+ constructor_name => undef,
+);
+
1;
__END__
or to examine L<Task::Moose> which aims to keep an up-to-date, easily
installable list of Moose extensions.
+=head1 TRANSLATIONS
+
+Much of the Moose documentation has been translated into other languages.
+
+=over 4
+
+=item Japanese
+
+Japanese docs can be found at L<http://perldoc.perlassociation.org/pod/Moose-Doc-JA/index.html>. The source POD files can be found in GitHub: L<http://github.com/jpa/Moose-Doc-JA>
+
+=back
+
=head1 BUILDING CLASSES WITH MOOSE
Moose makes every attempt to provide as much convenience as possible during
=item I<required =E<gt> (1|0)>
-This marks the attribute as being required. This means a I<defined> value must be
-supplied during class construction, and the attribute may never be set to
-C<undef> with an accessor.
+This marks the attribute as being required. This means a value must be
+supplied during class construction, I<or> the attribute must be lazy
+and have either a default or a builder. Note that c<required> does not
+say anything about the attribute's value, which can be C<undef>.
=item I<weak_ref =E<gt> (1|0)>
=item I<auto_deref =E<gt> (1|0)>
-This tells the accessor whether to automatically dereference the value returned.
-This is only legal if your C<isa> option is either C<ArrayRef> or C<HashRef>.
+This tells the accessor to automatically dereference the value of this
+attribute when called in list context. The accessor will still return a
+reference when called in scalar context. If this behavior isn't desirable,
+L<Moose::Meta::Attribute::Native::Trait::Array/elements> or
+L<Moose::Meta::Attribute::Native::Trait::Hash/elements> may be a better
+choice. The I<auto_deref> option is only legal if your I<isa> option is
+either C<ArrayRef> or C<HashRef>.
=item I<trigger =E<gt> $code>
The I<trigger> option is a CODE reference which will be called after
the value of the attribute is set. The CODE ref will be passed the
-instance itself and the updated value. You B<cannot> have a trigger on
-a read-only attribute.
+instance itself and the updated value. If the attribute already had a
+value, this will be passed as the third value to the trigger.
+
+You B<can> have a trigger on a read-only attribute.
B<NOTE:> Triggers will only fire when you B<assign> to the attribute,
either in the constructor, or using the writer. Default and built values will
B<not> cause the trigger to be fired.
-=item I<handles =E<gt> ARRAY | HASH | REGEXP | ROLE | CODE>
+=item I<handles =E<gt> ARRAY | HASH | REGEXP | ROLE | DUCKTYPE | CODE>
The I<handles> option provides Moose classes with automated delegation features.
This is a pretty complex and powerful option. It accepts many different option
which delegate to the C<node> and C<children> methods (respectively) of the Tree
instance stored in the C<parent> slot.
+You may also use an array reference to curry arguments to the original method.
+
+ has 'thing' => (
+ ...
+ handles => { set_foo => [ set => 'foo' ] },
+ );
+
+ # $self->set_foo(...) calls $self->thing->set('foo', ...)
+
+The first element of the array reference is the original method name, and the
+rest is a list of curried arguments.
+
=item C<REGEXP>
The regexp option works very similar to the ARRAY option, except that it builds
that this does B<not> include any method modifiers or generated attribute
methods (which is consistent with role composition).
+=item C<DUCKTYPE>
+
+With the duck type option, you pass a duck type object whose "interface" then
+becomes the list of methods to handle. The "interface" can be defined as; the
+list of methods passed to C<duck_type> to create a duck type object. For more
+information on C<duck_type> please check
+L<Moose::Util::TypeConstraints>.
+
=item C<CODE>
This is the option to use when you really want to do something funky. You should
but they are still a fairly advanced topic and too much to cover here, see
L<Moose::Cookbook::Meta::Recipe1> for more information.
-The default behavior here is to just load C<$metaclass_name>; however, we also
-have a way to alias to a shorter name. This will first look to see if
-B<Moose::Meta::Attribute::Custom::$metaclass_name> exists. If it does, Moose
-will then check to see if that has the method C<register_implementation>, which
-should return the actual name of the custom attribute metaclass. If there is no
-C<register_implementation> method, it will fall back to using
-B<Moose::Meta::Attribute::Custom::$metaclass_name> as the metaclass name.
+See L<Metaclass and Trait Name Resolution> for details on how a metaclass name
+is resolved to a class name.
=item I<traits =E<gt> [ @role_names ]>
attribute meta-object. This is very similar to the I<metaclass> option, but
allows you to use more than one extension at a time.
-See L<TRAIT NAME RESOLUTION> for details on how a trait name is
-resolved to a class name.
+See L<Metaclass and Trait Name Resolution> for details on how a trait name is
+resolved to a role name.
Also see L<Moose::Cookbook::Meta::Recipe3> for a metaclass trait
example.
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<builder
option docs in Class::MOP::Attribute|Class::MOP::Attribute/builder>
- and/or L<Moose::Cookbook::Basics::Recipe9> for more information.
+ and/or L<Moose::Cookbook::Basics::Recipe8> for more information.
=item I<default> => SCALAR | CODE
Class::MOP::Attribute|Class::MOP::Attribute/initializer> for more
information.
+=item I<documentation> => $string
+
+An arbitrary string that can be retrieved later by calling C<<
+$attr->documentation >>.
+
+
+
=back
=item B<has +$name =E<gt> %options>
In this case, we are basically taking the attribute which the role supplied
and altering it within the bounds of this feature.
+Note that you can only extend an attribute from either a superclass or a role,
+you cannot extend an attribute in a role that composes over an attribute from
+another role.
+
Aside from where the attributes come from (one from superclass, the other
from a role), this feature works exactly the same. This feature is restricted
somewhat, so as to try and force at least I<some> sanity into it. You are only
=item B<around $name|@names =E<gt> sub { ... }>
-This three items are syntactic sugar for the before, after, and around method
+These three items are syntactic sugar for the before, after, and around method
modifier features that L<Class::MOP> provides. More information on these may be
-found in the L<Class::MOP::Class documentation|Class::MOP::Class/"Method
-Modifiers"> for now.
+found in L<Moose::Manual::MethodModifiers> and the
+L<Class::MOP::Class documentation|Class::MOP::Class/"Method Modifiers">.
=item B<super>
This is very similar to the attribute traits feature. When you do
this, your class's C<meta> object will have the specified traits
-applied to it. See L<TRAIT NAME RESOLUTION> for more details.
+applied to it. See L<Metaclass and Trait Name Resolution> for more
+details.
-=head2 Trait Name Resolution
+=head2 Metaclass and 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
C<register_implementation> method, it will fall back to using
B<Moose::Meta::$type::Custom::Trait::$trait> as the trait name.
+The lookup method for metaclasses is the same, except that it looks
+for a class matching B<Moose::Meta::$type::Custom::$metaclass_name>.
+
If all this is confusing, take a look at
L<Moose::Cookbook::Meta::Recipe3>, which demonstrates how to create an
attribute trait.
a message. To subscribe, send an empty message to
L<moose-subscribe@perl.org>
-You can also visit us at L<#moose on
-irc.perl.org|irc://irc.perl.org/#moose>. This channel is quite active,
-and questions at all levels (on Moose-related topics ;) are welcome.
+You can also visit us at C<#moose> on L<irc://irc.perl.org/#moose>
+This channel is quite active, and questions at all levels (on Moose-related
+topics ;) are welcome.
=head1 ACKNOWLEDGEMENTS
Please report any bugs to C<bug-moose@rt.cpan.org>, or through the web
interface at L<http://rt.cpan.org>.
+You can also discuss feature requests or possible bugs on the Moose mailing
+list (moose@perl.org) or on IRC at L<irc://irc.perl.org/#moose>.
+
=head1 FEATURE REQUESTS
We are very strict about what features we add to the Moose core, especially
Stevan (stevan) Little E<lt>stevan@iinteractive.comE<gt>
+Jesse (doy) Luehrs E<lt>doy at tozt dot netE<gt>
+
Yuval (nothingmuch) Kogman
-Shawn (sartak) Moore
+Shawn (sartak) Moore E<lt>sartak@bestpractical.comE<gt>
+
+Hans Dieter (confound) Pearcey E<lt>hdp@pobox.comE<gt>
+
+Chris (perigrin) Prather
+
+Florian Ragwitz E<lt>rafl@debian.orgE<gt>
Dave (autarch) Rolsky E<lt>autarch@urth.orgE<gt>
Christian (chansen) Hansen
-Hans Dieter (confound) Pearcey
-
Eric (ewilhelm) Wilhelm
Guillermo (groditi) Roditi
Shlomi (rindolf) Fish
-Chris (perigrin) Prather
-
Wallace (wreis) Reis
Jonathan (jrockway) Rockway
Cory (gphat) Watson
+Dylan Hardison (doc fixes)
+
... and many other #moose folks
=head1 COPYRIGHT AND LICENSE
-Copyright 2006-2009 by Infinity Interactive, Inc.
+Copyright 2006-2010 by Infinity Interactive, Inc.
L<http://www.iinteractive.com>