Class::MOP::Class(3)
β¨ Class::MOP::Class β the manual page, bestie edition β¨
Okay so this is the page for Class::MOP::Class(3), which lives in the User Contributed Perl Documentation section. Yes it's long. No we're not skipping anything. Grab a snack. π
π NAME π
Class::MOP::Class β Class Meta Object. It's the meta object for your classes, iykyk.
πΈ VERSION πΈ
version 2.4000
π SYNOPSIS π
Lowkey the fastest way to get it is just to look at it, so:
# assuming that class Foo
# has been defined, you can
# use this for introspection ...
# add a method to Foo ...
Foo->meta->add_method( 'bar' => sub {...} )
# get a list of all the classes searched
# the method dispatcher in the correct order
Foo->meta->class_precedence_list()
# remove a method from Foo
Foo->meta->remove_method('bar');
# or use this to actually create classes ...
Class::MOP::Class->create(
'Bar' => (
version => '0.01',
superclasses => ['Foo'],
attributes => [
Class::MOP::Attribute->new('$bar'),
Class::MOP::Attribute->new('$baz'),
],
methods => {
calculate_bar => sub {...},
construct_baz => sub {...}
}
)
);
π¦ DESCRIPTION π¦
Not me about to explain the biggest one first. The Class Protocol is the largest and most complex part of the Class::MOP meta-object protocol. It's the thing that controls introspection and manipulation of Perl 5 classes β and yes, it can literally create them too. The best way to actually understand what this module can do is to read the docs for each of its methods. That's the vibe. π
π INHERITANCE π
Class::MOP::Class is a subclass of Class::MOP::Module. Family tree, but make it meta.
π METHODS π
π§ Class construction
These methods all create new Class::MOP::Class objects. Those objects can represent classes that already exist, or they can be used to build brand new classes from scratch. Main character energy fr.
The metaclass object for a given class is a singleton. So if you try to create a metaclass for the same class twice, you don't get a second one β you just get the existing object back. No dupes allowed. π βοΈ
Class::MOP::Class->create($package_name, %options)
This one creates a new Class::MOP::Class object with the package name you give it. It accepts a bunch of options:
versionβ an optional version number for the newly created package.authorityβ an optional authority for the newly created package. See"authority" in Class::MOP::Modulefor more details.superclassesβ an optional array reference of superclass names.methodsβ an optional hash reference of methods for the class. The keys of the hash reference are method names, and the values are subroutine references.attributesβ an optional array reference ofClass::MOP::Attributeobjects.meta_nameβ specifies the name to install the"meta"method for this class under. If it's not passed,"meta"is assumed. And if"undef"is explicitly given, no meta method will be installed at all.weakenβ if true, the metaclass that gets stored in the global cache will be a weak reference.
Classes created this way are destroyed once the metaclass they're attached to goes out of scope, and they get removed from Perl's internal symbol table.
All instances of a class with a weakened metaclass keep a special reference to the metaclass object, which stops the metaclass from going out of scope while any instances still exist.
This only works if the instance is based on a hash reference, however.
Class::MOP::Class->create_anon_class(%options)
Works just like "Class::MOP::Class->create" but it makes an "anonymous" class. Tbh the class does have a name β it's just a unique name generated internally by this module. Mystery girl. π΅οΈβοΈ
It accepts the same "superclasses", "methods", and "attributes" parameters that "create" accepts.
It also accepts a "cache" option. If that's "true", then the anonymous class gets cached based on its superclasses and roles. And if an existing anonymous class in the cache has the same superclasses and roles, it gets reused.
Anonymous classes default to "weaken => 1" if cache is "false", although you can override that.
Class::MOP::Class->initialize($package_name, %options)
This method initializes a Class::MOP::Class object for the named package. Unlike "create", it will not create a new class.
The whole point of this one is to retrieve a Class::MOP::Class object so you can introspect an existing class.
If an existing Class::MOP::Class object already exists for the named package, it will be returned, and any options you provide will be ignored! π
If the object doesn't exist yet, it will be created.
The valid options you can pass are "attribute_metaclass", "method_metaclass", "wrapped_method_metaclass", and "instance_metaclass". All of them are optional and default to the appropriate class in the Class::MOP distribution.
π Object instance construction and cloning
These methods are all about creating and/or cloning object instances. Cute little object babies.
$metaclass->clone_object($instance, %params)
Clones an existing object instance. Any parameters you provide will override existing attribute values in the object.
It's a convenience method for cloning an object instance and then blessing it into the appropriate package.
You could implement a clone method in your class using it, like this:
sub clone {
my ($self, %params) = @_;
$self->meta->clone_object($self, %params);
}
$metaclass->rebless_instance($instance, %params)
Changes the class of $instance to the metaclass's class.
You can only rebless an instance into a subclass of its current class. If you pass extra parameters, they get 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 calls "rebless_instance_away" on the instance's current metaclass. That method gets passed the instance, the new metaclass, and any parameters you specified to "rebless_instance". By default, "rebless_instance_away" does nothing β it's purely a hook.
$metaclass->rebless_instance_back($instance)
Does the same thing as "rebless_instance", except you can only rebless an instance into one of its superclasses. Any attributes that don't exist in the superclass get deinitialized.
This is a much more dangerous operation than "rebless_instance", especially when multiple inheritance is involved, so use this carefully! β οΈ
$metaclass->new_object(%params)
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, instead of having Class::MOP generate it for you. Mostly useful for using Class::MOP with foreign classes that generate instances using their own constructors.
$metaclass->instance_metaclass
Returns the class name of the instance metaclass. See Class::MOP::Instance for more info on the instance metaclass.
$metaclass->get_meta_instance
Returns an instance of the "instance_metaclass" to be used in the construction of a new instance of the class.
π Informational predicates
Just a few predicate methods for asking questions about the class itself. Nosy but make it legal.
$metaclass->is_anon_class
Returns true if the class was created by calling "Class::MOP::Class->create_anon_class".
$metaclass->is_mutable
Returns true if the class is still mutable.
$metaclass->is_immutable
Returns true if the class has been made immutable.
$metaclass->is_pristine
A class is not pristine if it has non-inherited attributes, or if it has any generated methods.
π¦ Inheritance Relationships
$metaclass->superclasses(@superclasses)
A read-write accessor representing the superclass relationships of the metaclass's class.
It's basically sugar around getting and setting @ISA.
$metaclass->class_precedence_list
Returns a list of all of the class's ancestor classes. The classes come back in method dispatch order.
$metaclass->linearized_isa
Returns a list based on "class_precedence_list" but with all duplicates removed. Cleaned up, filtered, iconic. β¨
$metaclass->subclasses
Returns a list of all subclasses for this class β even indirect subclasses. Everyone in the bloodline.
$metaclass->direct_subclasses
Returns a list of immediate subclasses for this class, which does not include indirect subclasses.
π Method introspection and creation
These methods let you introspect a class's methods, and also add, remove, or change them.
Determining what is truly a method in a Perl 5 class requires some heuristics (aka guessing). Not our fault, that's just Perl.
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::Util 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. π
$metaclass->get_method($method_name)
Returns a Class::MOP::Method for the specified $method_name. If the class doesn't have that method, it returns "undef".
$metaclass->has_method($method_name)
Returns a boolean saying whether or not the class defines the named method. It does not include methods inherited from parent classes.
$metaclass->get_method_list
Returns a list of method names for all methods defined in this class.
$metaclass->add_method($method_name, $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, that object gets stored as part of the class's method map directly. If you don't, the meta information will have to be recreated later β and it may be incorrect. π
okay so real quick, bestie: if you hand this thing an actual method object, it will clone that object whenever the object's package name doesn't match the class name. why do we even do that? because it lets us keep receipts on where any method originally came from β especially methods that got added from other classes (yes, we're looking at you, Moose roles π).
$metaclass->remove_method($method_name)
Yeets the named method out of the class. What do you get back? The Class::MOP::Method object for that method. π
$metaclass->method_metaclass
Hands you the class name of the method metaclass. Want the full lore on the method metaclass? Go read Class::MOP::Method. π
$metaclass->wrapped_method_metaclass
Gives you the class name of the wrapped method metaclass. Again, more deets live in Class::MOP::Method::Wrapped. β¨
$metaclass->get_all_methods
This one walks the whole inheritance hierarchy and gives you back a list of all the Class::MOP::Method objects for this class and its parents. the whole family tree, no cap π³
$metaclass->find_method_by_name($method_name)
Returns a Class::MOP::Method for the $method_name you asked about. If the class doesn't have that method? You get undef, sorry babe π
But here's the tea β unlike get_method, this one will go looking for the named method up in the superclasses. so it's the thorough friend π«Ά
$metaclass->get_all_method_names
Returns a list of method names for every single one of this class's methods β inherited ones included. the full roster π
$metaclass->find_all_methods_by_name($method_name)
This hunts for the named method in the class and all of its parents. It returns every matching method it finds in the inheritance tree, so yeah, you're getting a list back.
Each method comes back as a hash reference with three keys: name, class, and code. The code key holds a Class::MOP::Method object as its value.
And the list of methods is distinct. no dupes allowed π«
$metaclass->find_next_method_by_name($method_name)
Returns the first method in any superclass that matches the given name. Basically it's the method that SUPER::$method_name would dispatch to. iconic behavior π
πΈ Attribute introspection and creation πΈ
Okay so real talk: because Perl 5 has no core concept of attributes in classes, we can only give you info about attributes that were added through this class's methods. If an attribute is defined in terms of "regular" Perl 5 methods? We literally cannot discover anything about it. sorry bestie, that's just the rules π
$metaclass->get_attribute($attribute_name)
Returns a Class::MOP::Attribute for the $attribute_name you specified. If the class doesn't have that attribute, it returns undef.
NOTE:get_attributedoes not search superclasses. If that's what you need, you have to usefind_attribute_by_nameinstead. don't come for me, it's just how she works π
$metaclass->has_attribute($attribute_name)
Returns a boolean telling you whether or not the class defines the named attribute. Heads up: it does not include attributes inherited from parent classes. this is a "what's mine" situation only π
$metaclass->get_attribute_list
Returns a list of attribute names for all attributes defined in this class. Note that this operates on the current class only β it does not traverse the inheritance hierarchy. π
$metaclass->get_all_attributes
Now this one traverses the inheritance hierarchy and returns a list of all the Class::MOP::Attribute objects for this class and its parents. the full collection π
$metaclass->find_attribute_by_name($attribute_name)
Returns a Class::MOP::Attribute for the $attribute_name you specified. If the class doesn't have it, you get undef.
Unlike get_attribute, this one will look for the named attribute in superclasses. she goes the extra mile β¨
$metaclass->add_attribute(...)
This method accepts either an existing Class::MOP::Attribute object, or parameters suitable for passing to that class's new method.
Whatever attribute you provide gets added to the class. π«Ά
Any accessor methods that the attribute defines get added to the class too, at the moment the attribute is added.
And if an attribute of the same name already exists? The old attribute gets removed first. out with the old, in with the new π
$metaclass->remove_attribute($attribute_name)
Removes the named attribute from the class, and the Class::MOP::Attribute object.
Removing an attribute also removes any accessor methods that the attribute defined. π§Ή
But wait β important caveat: removing an attribute only affects future object instances created for this class, not existing instances. the ones already out there are living their lives, unaffected π
$metaclass->attribute_metaclass
Returns the class name of the attribute metaclass for this class. By default, that's Class::MOP::Attribute. β
π Overload introspection and creation π
These methods give you an API to the core overload functionality. let's get into it π¦
$metaclass->is_overloaded
Returns true if overloading is enabled for this class. Corresponds to is_overloaded in Devel::OverloadInfo.
$metaclass->get_overloaded_operator($op)
Returns the Class::MOP::Overload object corresponding to the operator named $op, if one exists for this class.
$metaclass->has_overloaded_operator($op)
Returns whether or not the operator $op is overloaded for this class.
$metaclass->get_overload_list
Returns a list of operator names which have been overloaded. (See Overloadable Operations in overload for the list of valid operator names.) π
$metaclass->get_all_overloaded_operators
Returns a list of Class::MOP::Overload objects corresponding to the operators that have been overloaded.
$metaclass->add_overloaded_operator($op, $impl)
Overloads the operator $op for this class. The $impl can be a coderef, a method name, or a Class::MOP::Overload object. Corresponds to use overload $op => $impl; π₯
$metaclass->remove_overloaded_operator($op)
Removes overloading for operator $op. Corresponds to no overload $op;
$metaclass->get_overload_fallback_value
Returns the overload fallback setting for the package.
$metaclass->set_overload_fallback_value($fallback)
Sets the overload fallback setting for the package.
π§ Class Immutability π§
Making a class immutable "freezes" the class definition. After that? You can no longer call methods which alter the class β so no adding or removing methods or attributes. she's locked in π
Why would you do this? Because making a class immutable lets us optimize it by inlining some methods, and it also lets us optimize some methods on the metaclass object itself. glow-up optimization π β¨
Once immutabilized, the metaclass object caches most informational methods that return info about methods or attributes. And methods that would alter the class β like add_attribute and add_method β will throw an error on an immutable metaclass object. do not try it π
Also, heads up: the immutabilization system in Moose takes much greater advantage of the inlining features than Class::MOP itself does. Moose is just built different, fr fr π
$metaclass->make_immutable(%options)
This method creates an immutable transformer and uses it to make the class and its metaclass object immutable, and returns true. (And like, don't go relying on the details of that return value beyond whether it's true. just trust the truthiness π)
This method accepts the following options:
inline_accessorsinline_constructorinline_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).
This defaults to Class::MOP::Class::Immutable::Trait.
constructor_name
This is the constructor method name. This defaults to new.
constructor_class
The name of the method metaclass for constructors. It will be used to generate the inlined constructor. This defaults to Class::MOP::Method::Constructor.
replace_constructor
This is a boolean indicating whether an existing constructor should be replaced when inlining a constructor. This defaults to false.
destructor_class
The name of the method metaclass for destructors. It will be used to generate the inlined destructor. This defaults to Class::MOP::Method::Denstructor.
replace_destructor
This is a boolean indicating whether an existing destructor should be replaced when inlining a destructor. This defaults to false.
$metaclass->immutable_options
Returns a hash of the options used when making the class immutable β including both the defaults and anything supplied by the user in the call to $metaclass->make_immutable. Super handy if you need to temporarily make a class mutable and then restore immutability exactly as it was before. keeping the receipts, always π§Ύ
$metaclass->make_mutable
Calling this method reverses the immutabilization transformation. she's free again π¦
π Method Modifiers π
Method modifiers are hooks that let a method be wrapped with before, after and around method modifiers. Every time a method is called, its modifiers get called too. it's a whole squad showing up together π
And a class can modify its own methods, as well as methods defined in parent classes. no boundaries β¨
How method modifiers work?
Method modifiers work by wrapping the original method and then replacing it in the class's symbol table. The wrappers 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. Why? Because their whole purpose is not to filter the input and output of the primary method β that job belongs to the 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. it's called β¨designβ¨ bestie
Of course, if you have more complex needs, you can use the around modifier, which lets you change both the parameters passed to the wrapped method and its return value. full control, main character energy π
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 look something like this:
before 2
before 1
around 2
around 1
primary
around 1
around 2
after 1
after 2
What is the performance impact?
Okay so like, yes, method modifiers do have a performance cost, bestie β that's just math. But we literally tried so hard to make that cost directly proportional to how many modifier features you actually use. β¨
The wrapping method is doing the absolute most to only do the work it absolutely has to. To pull that off, we moved some of the performance cost to set-up time, where it's way easier to amortize. iykyk π
All that being said, our benchmarks said this:
simple wrapper with no modifiers 100% slower
simple wrapper with simple before modifier 400% slower
simple wrapper with simple after modifier 450% slower
simple wrapper with simple around modifier 500-550% slower
simple wrapper with all 3 modifiers 1100% slower
Not gonna lie, those numbers look scary π but remember β every feature comes with some cost. For perspective? Just doing a simple AUTOLOAD that does nothing but extract the name of the method called and return it costs about 400% over a normal method call. So. Perspective. π«Ά
$metaclass->add_before_method_modifier($method_name, $code)β this wraps the specified method with the supplied subroutine reference. The modifier gets called as a method itself, and it receives the same arguments that get passed to the method. β¨
When the modifier exits, the wrapped method gets called. And the return value of the modifier? Ignored. literally doesn't matter, we're not reading it π
$metaclass->add_after_method_modifier($method_name, $code)β same deal, wraps the specified method with the supplied subroutine reference. The modifier gets called as a method itself and receives the same arguments as are passed to the method. π
This time it's flipped: when the wrapped method exits, then the modifier gets called.
Return value of the modifier? Ignored again. periodt.
$metaclass->add_around_method_modifier($method_name, $code)β wraps the specified method with the supplied subroutine reference. πΈ
The first argument passed to the modifier is a subroutine reference to the wrapped method. The second argument is the object, and after that come any arguments passed when the method is called.
The around modifier can choose to call the original method, and it also gets to choose what arguments to pass if it does. main character energy fr fr π
The return value of the modifier is what the caller sees. so if you mess that up, that's on you bestie π
Introspection πβ¨
Class::MOP::Class->metaβ this will return aClass::MOP::Classinstance for this class. π¦
Also worth noting: Class::MOP will actually bootstrap this module by installing a number of attribute meta-objects into its metaclass. iconic behavior tbh.
AUTHORS ππ
- Stevan Little
<stevan@cpan.org> - Dave Rolsky
<autarch@urth.org> - Jesse Luehrs
<doy@cpan.org> - Shawn M Moore
<sartak@cpan.org> - ΧΧΧΧ Χ§ΧΧ'ΧΧ (Yuval Kogman)
<nothingmuch@woobling.org> - Karen Etheridge
<ether@cpan.org> - Florian Ragwitz
<rafl@debian.org> - Hans Dieter Pearcey
<hdp@cpan.org> - Chris Prather
<chris@prather.org> - Matt S Trout
<mstrout@cpan.org>
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. π«Ά
and that's the whole page bestie!! πβ¨π This one shipped as perl v5.42.0 on 2025-07-25, and it's the Class::MOP::Class(3) page β go forth and meta-program, you absolute legend ππ
π
π¦ where this page comes from
- fedora 43: perl-Moose 2.4000-4.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms