The Class Protocol is the largest and most complex part of the Class::MOP meta-object protocol. It controls the introspection and manipulation of Perl 5 classes, and it can create them as well. The best way to understand what this module can do is to read the documentation for each of its methods.

This method will initialize a Class::MOP::Class object for the named package. Unlike create, this method will not create a new class.

The purpose of this method is to retrieve a Class::MOP::Class object for introspecting an existing class.

If an existing Class::MOP::Class object exists for the named package, it will be returned, and any options provided will be ignored!

If the object does not yet exist, it will be created.

The valid options that can be passed to this method are attribute_metaclass, method_metaclass, wrapped_method_metaclass, and instance_metaclass. These are all optional, and default to the appropriate class in the Class::MOP distribution.

You can only rebless an instance into a subclass of its current class. If you pass any additional parameters, these will be treated like constructor parameters and used to initialize the object's attributes. Any existing attributes that are already set will be overwritten.

Before reblessing the instance, this method will call rebless_instance_away on the instance's current metaclass. This method will be passed the instance, the new metaclass, and any parameters specified to rebless_instance. By default, rebless_instance_away does nothing; it is merely a hook.

This method is used to create a new object of the metaclass's class. Any parameters you provide are used to initialize the instance's attributes. A special __INSTANCE__ key can be passed to provide an already generated instance, rather than having Class::MOP generate it for you. This is mostly useful for using Class::MOP with foreign classes which generate instances using their own constructors.

These methods allow you to introspect a class's methods, as well as add, remove, or change methods.

Determining what is truly a method in a Perl 5 class requires some heuristics (aka guessing).

Methods defined outside the package with a fully qualified name (sub Package::name { ... }) will be included. Similarly, methods named with a fully qualified name using Sub::Name are also included.

However, we attempt to ignore imported functions.

Ultimately, we are using heuristics to determine what truly is a method in a class, and these heuristics may get the wrong answer in some edge cases. However, for most "normal" cases the heuristics work correctly.

This method takes a method name and a subroutine reference, and adds the method to the class.

The subroutine reference can be a Class::MOP::Method, and you are strongly encouraged to pass a meta method object instead of a code reference. If you do so, that object gets stored as part of the class's method map directly. If not, the meta information will have to be recreated later, and may be incorrect.

If you provide a method object, this method will clone that object if the object's package name does not match the class name. This lets us track the original source of any methods added from other classes (notably Moose roles).

Because Perl 5 does not have a core concept of attributes in classes, we can only return information about attributes which have been added via this class's methods. We cannot discover information about attributes which are defined in terms of "regular" Perl 5 methods.

Making a class immutable "freezes" the class definition. You can no longer call methods which alter the class, such as adding or removing methods or attributes.

Making a class immutable lets us optimize the class by inlining some methods, and also allows us to optimize some methods on the metaclass object itself.

After immutabilization, the metaclass object will cache most informational methods that returns information about methods or attributes. Methods which would alter the class, such as add_attribute and add_method, will throw an error on an immutable metaclass object.

The immutabilization system in Moose takes much greater advantage of the inlining features than Class::MOP itself does.

This method will create an immutable transformer and use it to make the class and its metaclass object immutable, and returns true (you should not rely on the details of this value apart from its truth).

This method accepts the following options:

inline_accessors

inline_constructor

inline_destructor

These are all booleans indicating whether the specified method(s) should be inlined.

By default, accessors and the constructor are inlined, but not the destructor.

immutable_trait

The name of a class which will be used as a parent class for the metaclass object being made immutable. This "trait" implements the post-immutability functionality of the metaclass (but not the transformation itself).

Returns a hash of the options used when making the class immutable, including both defaults and anything supplied by the user in the call to $metaclass->make_immutable. This is useful if you need to temporarily make a class mutable and then restore immutability as it was before.

Method modifiers work by wrapping the original method and then replacing it in the class's symbol table. The wrappers will handle calling all the modifiers in the appropriate order and preserving the calling context for the original method.

The return values of before and after modifiers are ignored. This is because their purpose is not to filter the input and output of the primary method (this is done with an around modifier).

This may seem like an odd restriction to some, but doing this allows for simple code to be added at the beginning or end of a method call without altering the function of the wrapped method or placing any extra responsibility on the code of the modifier.

Of course if you have more complex needs, you can use the around modifier which allows you to change both the parameters passed to the wrapped method, as well as its return value.

Before and around modifiers are called in last-defined-first-called order, while after modifiers are called in first-defined-first-called order. So the call tree might looks something like this:

before 2
before 1
around 2
around 1
primary
around 1
around 2
after 1
after 2

These numbers may seem daunting, but you must remember, every feature comes with some cost. To put things in perspective, just doing a simple AUTOLOAD which does nothing but extract the name of the method called and return it costs about 400% over a normal method call.