This commit is contained in:
214
CPAN/Moose/Manual/MOP.pod
Normal file
214
CPAN/Moose/Manual/MOP.pod
Normal file
@@ -0,0 +1,214 @@
|
||||
# PODNAME: Moose::Manual::MOP
|
||||
# ABSTRACT: The Moose (and Class::MOP) meta API
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=encoding UTF-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Moose::Manual::MOP - The Moose (and Class::MOP) meta API
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
version 2.2207
|
||||
|
||||
=head1 INTRODUCTION
|
||||
|
||||
Moose provides a powerful introspection API built on top of
|
||||
C<Class::MOP>. "MOP" stands for Meta-Object Protocol. In plainer
|
||||
English, a MOP is an API for performing introspection on classes,
|
||||
attributes, methods, and so on.
|
||||
|
||||
In fact, it is C<Class::MOP> that provides many of Moose's core
|
||||
features, including attributes, before/after/around method modifiers,
|
||||
and immutability. In most cases, Moose takes an existing C<Class::MOP>
|
||||
class and subclasses it to add additional features. Moose also adds
|
||||
some entirely new features of its own, such as roles, the augment
|
||||
modifier, and types.
|
||||
|
||||
If you're interested in the MOP, it's important to know about
|
||||
C<Class::MOP> so you know what docs to read. Often, the introspection
|
||||
method that you're looking for is defined in a C<Class::MOP> class,
|
||||
rather than Moose itself.
|
||||
|
||||
The MOP provides more than just I<read-only> introspection. It also
|
||||
lets you add attributes and methods, apply roles, and much more. In
|
||||
fact, all of the declarative Moose sugar is simply a thin layer on top
|
||||
of the MOP API.
|
||||
|
||||
If you want to write Moose extensions, you'll need to learn some of
|
||||
the MOP API. The introspection methods are also handy if you want to
|
||||
generate docs or inheritance graphs, or do some other runtime
|
||||
reflection.
|
||||
|
||||
This document is not a complete reference for the meta API. We're just
|
||||
going to cover some of the highlights, and give you a sense of how it
|
||||
all works. To really understand it, you'll have to read a lot of other
|
||||
docs, and possibly even dig into the Moose guts a bit.
|
||||
|
||||
=head1 GETTING STARTED
|
||||
|
||||
The usual entry point to the meta API is through a class's metaclass
|
||||
object, which is a L<Moose::Meta::Class>. This is available by calling
|
||||
the C<meta> method on a class or object:
|
||||
|
||||
package User;
|
||||
|
||||
use Moose;
|
||||
|
||||
my $meta = __PACKAGE__->meta;
|
||||
|
||||
The C<meta> method is added to a class when it uses Moose.
|
||||
|
||||
You can also use C<< Class::MOP::Class->initialize($name) >> to get a
|
||||
metaclass object for any class. This is safer than calling C<<
|
||||
$class->meta >> when you're not sure that the class has a meta method.
|
||||
|
||||
The C<< Class::MOP::Class->initialize >> constructor will return an
|
||||
existing metaclass if one has already been created (via Moose or some
|
||||
other means). If it hasn't, it will return a new C<Class::MOP::Class>
|
||||
object. This will work for classes that use Moose, meta API classes,
|
||||
and classes which don't use Moose at all.
|
||||
|
||||
=head1 USING THE METACLASS OBJECT
|
||||
|
||||
The metaclass object can tell you about a class's attributes, methods,
|
||||
roles, parents, and more. For example, to look at all of the class's
|
||||
attributes:
|
||||
|
||||
for my $attr ( $meta->get_all_attributes ) {
|
||||
print $attr->name, "\n";
|
||||
}
|
||||
|
||||
The C<get_all_attributes> method is documented in
|
||||
C<Class::MOP::Class>. For Moose-using classes, it returns a list of
|
||||
L<Moose::Meta::Attribute> objects for attributes defined in the class
|
||||
and its parents.
|
||||
|
||||
You can also get a list of methods:
|
||||
|
||||
for my $method ( $meta->get_all_methods ) {
|
||||
print $method->fully_qualified_name, "\n";
|
||||
}
|
||||
|
||||
Now we're looping over a list of L<Moose::Meta::Method> objects. Note
|
||||
that some of these objects may actually be a subclass of
|
||||
L<Moose::Meta::Method>, as Moose uses different classes to represent
|
||||
wrapped methods, delegation methods, constructors, etc.
|
||||
|
||||
We can look at a class's parent classes and subclasses:
|
||||
|
||||
for my $class ( $meta->linearized_isa ) {
|
||||
print "$class\n";
|
||||
}
|
||||
|
||||
for my $subclass ( $meta->subclasses ) {
|
||||
print "$subclass\n";
|
||||
}
|
||||
|
||||
Note that both these methods return class I<names>, not metaclass
|
||||
objects.
|
||||
|
||||
=head1 ALTERING CLASSES WITH THE MOP
|
||||
|
||||
The metaclass object can change the class directly, by adding
|
||||
attributes, methods, etc.
|
||||
|
||||
As an example, we can add a method to a class:
|
||||
|
||||
$meta->add_method( 'say' => sub { print @_, "\n" } );
|
||||
|
||||
Or an attribute:
|
||||
|
||||
$meta->add_attribute( 'size' => ( is => 'rw', isa => 'Int' ) );
|
||||
|
||||
Obviously, this is much more cumbersome than using Perl syntax or
|
||||
Moose sugar for defining methods and attributes, but this API allows
|
||||
for very powerful extensions.
|
||||
|
||||
You might remember that we've talked about making classes immutable
|
||||
elsewhere in the manual. This is a good practice. However, once a
|
||||
class is immutable, calling any of these update methods will throw an
|
||||
exception.
|
||||
|
||||
You can make a class mutable again simply by calling C<<
|
||||
$meta->make_mutable >>. Once you're done changing it, you can
|
||||
restore immutability by calling C<< $meta->make_immutable >>.
|
||||
|
||||
However, the most common use for this part of the meta API is as
|
||||
part of Moose extensions. These extensions should assume that they are
|
||||
being run before you make a class immutable.
|
||||
|
||||
=head1 GOING FURTHER
|
||||
|
||||
If you're interested in extending Moose, we recommend reading all of
|
||||
the "Meta" and "Extending" recipes in the L<Moose::Cookbook>. Those
|
||||
recipes show various practical applications of the MOP.
|
||||
|
||||
If you'd like to write your own extensions, one of the best ways to
|
||||
learn more about this is to look at other similar extensions to see
|
||||
how they work. You'll probably also need to read various API docs,
|
||||
including the docs for the various C<Moose::Meta::*> and
|
||||
C<Class::MOP::*> classes.
|
||||
|
||||
Finally, we welcome questions on the Moose mailing list and
|
||||
IRC. Information on the mailing list, IRC, and more references can be
|
||||
found in the L<Moose.pm docs|Moose/GETTING HELP>.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Stevan Little <stevan@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
Dave Rolsky <autarch@urth.org>
|
||||
|
||||
=item *
|
||||
|
||||
Jesse Luehrs <doy@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
Shawn M Moore <sartak@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
|
||||
|
||||
=item *
|
||||
|
||||
Karen Etheridge <ether@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
Florian Ragwitz <rafl@debian.org>
|
||||
|
||||
=item *
|
||||
|
||||
Hans Dieter Pearcey <hdp@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
Chris Prather <chris@prather.org>
|
||||
|
||||
=item *
|
||||
|
||||
Matt S Trout <mstrout@cpan.org>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2006 by Infinity Interactive, Inc.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user