Moose::...Concepts(3)

๐Ÿ’– NAME ๐Ÿ’–

Moose::Manual::Concepts โ€” the Moose OO concepts tour, bestie. This is Moose::...Concepts(3) and we're gonna make it make sense.


๐ŸŒธ VERSION ๐ŸŒธ

version 2.4000 โœจ


๐Ÿฆ‹ MOOSE CONCEPTS (VS "OLD SCHOOL" Perl) ๐Ÿฆ‹

Back in the day, you probably didn't sit around thinking about the difference between packages and classes, attributes and methods, constructors and methods, etc. But with Moose, these are all conceptually separate things, even though under the hood they're all just plain old Perl doing its thing. ๐Ÿ’…

Our meta-object protocol (aka MOP) gives you well-defined introspection for each one of those concepts, and Moose in turn hands you distinct sugar for each of them. Moose also brings in extra concepts like roles, method modifiers, and declarative delegation. ๐ŸŽ€

Knowing what all of these actually mean in Moose-speak โ€” and how people used to do them in old school Perl 5 OO โ€” is genuinely a great way to start learning Moose. fr fr.


๐Ÿ‘‘ Class

The moment you say use Moose in a package, congrats, your package is now a class. At its simplest, a class is just attributes and/or methods. It can also have roles, method modifiers, and more. ๐Ÿซถ

  • A class has zero or more attributes.
  • A class has zero or more methods.
  • A class has zero or more superclasses (aka parent classes). A class inherits from its superclass(es).
  • A class has zero or more method modifiers. These modifiers can apply to its own methods or to methods inherited from its ancestors.
  • A class does (and consumes) zero or more roles.
  • A class has a constructor and a destructor. Moose gives you these "for free". ๐Ÿ˜ญ generous
  • The constructor accepts named parameters corresponding to the class's attributes, and uses them to initialize an object instance.
  • A class has a metaclass, which in turn has meta-attributes, meta-methods, and meta-roles. This metaclass describes the class.
  • A class is usually analogous to a category of nouns, like "People" or "Users".
package Person;

use Moose;
# now it's a Moose class!

๐ŸŽ€ Attribute

An attribute is a property of the class that defines it. It always has a name, and it may have a number of other properties too.

Those properties can include a read/write flag, a type, accessor method names, delegations, a default value, and more. โœจ

Attributes are not methods, but defining them causes various accessor methods to be created. At minimum, a normal attribute gets a reader accessor method. Lots of attributes have other methods too, like a writer method, a clearer method, or a predicate method ("has it been set?").

An attribute may also define delegations, which create additional methods based on the delegation mapping.

By default, Moose stores attributes in the object instance, which is a hashref โ€” but this is invisible to the author of a Moose-based class! Best to think of Moose attributes as "properties" of the opaque object instance. You reach those properties through well-defined accessor methods. ๐Ÿ’…

An attribute is something that the class's members have. For example, People have first and last names. Users have passwords and last login datetimes.

has 'first_name' => (
    is  => 'rw',
    isa => 'Str',
);

โญ Method

A method is very straightforward, no notes. Any subroutine you define in your class is a method.

Methods correspond to verbs, and they're what your objects can do. For example, a User can login.

sub login { ... }

๐ŸŒˆ Role

A role is something that a class does. We also say that classes consume roles. For example, a Machine class might do the Breakable role, and so could a Bone class. A role is how you define some concept that cuts across multiple unrelated classes โ€” like "breakability", or "has a color". ๐Ÿ’…

  • A role has zero or more attributes.
  • A role has zero or more methods.
  • A role has zero or more method modifiers.
  • A role has zero or more required methods.

A required method is not implemented by the role. Required methods are how a role declares "to use this role you must implement this method".

  • A role has zero or more excluded roles.

An excluded role is a role that the role doing the excluding says it cannot be combined with.

Roles are composed into classes (or other roles). When a role is composed into a class, its attributes and methods get "flattened" into the class. Roles do not show up in the inheritance hierarchy. When a role is composed, its attributes and methods appear as if they were defined in the consuming class. ๐Ÿ‘‘

Roles are somewhat like mixins or interfaces in other OO languages.

package Breakable;

use Moose::Role;

requires 'break';

has 'is_broken' => (
    is  => 'rw',
    isa => 'Bool',
);

after 'break' => sub {
    my $self = shift;

    $self->is_broken(1);
};

๐Ÿงš Method modifiers

A method modifier is a hook that gets called when a named method is called. For example, you could say "before calling login(), call this modifier first". Modifiers come in different flavors like before, after, around, and augment, and you can apply more than one modifier to a single method. ๐ŸŽ€

Method modifiers are often used as an alternative to overriding a method in a parent class. They're also used in roles as a way of modifying methods in the consuming class.

Under the hood, a method modifier is just a plain old Perl subroutine that gets called before or after (or around, etc.) some named method.

before 'login' => sub {
    my $self = shift;
    my $pw   = shift;

    warn "Called login() with $pw\n";
};

๐Ÿ’œ Type

Moose also comes with a (miniature) type system. This lets you define types for attributes. Moose has a set of built-in types based on the types Perl provides in its core, such as Str, Num, Bool, HashRef, etc. โœจ

On top of that, every class name in your application can also be used as a type name. ๐Ÿ‘‘

And finally, you can define your own types with their own constraints. For example, you could define a PosInt type, a subtype of Int which only allows positive numbers.


๐Ÿฆ‹ Delegation

Moose attributes provide declarative syntax for defining delegations. A delegation is a method which in turn calls some method on an attribute to do its real work. Lowkey elegant.


๐ŸŽ€ Constructor

A constructor creates an object instance for the class. In old school Perl, this was usually done by defining a method called new() which in turn called bless on a reference.

With Moose, this new() method is created for you, and it simply does the right thing. You should never need to define your own constructor! ๐Ÿ’…

Sometimes you want to do something whenever an object is created. In those cases, you can provide a BUILD() method in your class. Moose will call this for you after creating a new object. ๐Ÿซถ


๐Ÿฅ€ Destructor

This is a special method called when an object instance goes out of scope. You can specialize what your class does in this method if you need to, but you usually don't. No cap.

With old school Perl 5, this is the DESTROY() method, but with Moose it's the DEMOLISH() method. ๐Ÿ˜ญ iconic rename


โญ Object instance

An object instance is a specific noun in the class's "category". For example, one specific Person or User. An instance is created by the class's constructor.

An instance has values for its attributes. For example, a specific person has a first and last name.

In old school Perl 5, this is often a blessed hash reference. With Moose, you should never need to know what your object instance actually is. (Okay fine, it's usually a blessed hashref with Moose too. ๐Ÿ™ˆ)


๐ŸŒˆ Moose vs old school summary

  • Class A package with no introspection other than mucking about in the symbol table. With Moose, you get well-defined declaration and introspection. โœจ
  • Attributes Hand-written accessor methods, symbol table hackery, or a helper module like Class::Accessor. With Moose, these are declaratively defined, and distinct from methods. ๐Ÿ’…
  • Method These are pretty much the same in Moose as in old school Perl. fr fr.
  • Roles Class::Trait or Class::Role, or maybe mixin.pm. With Moose, they're part of the core feature set, and are introspectable like everything else. ๐Ÿ‘‘
  • Method Modifiers Could only be done through serious symbol table wizardry, and you probably never saw this before (at least in Perl 5). ๐Ÿ’€
  • Type Hand-written parameter checking in your new() method and accessors. With Moose, you define types declaratively, and then use them by name with your attributes.
  • Delegation Class::Delegation or Class::Delegator, but probably even more hand-written code. With Moose, this is also declarative. ๐ŸŽ€
  • Constructor A new() method which calls bless on a reference. Comes for free when you define a class with Moose.
  • Destructor A DESTROY() method. With Moose, this is called DEMOLISH().
  • Object Instance A blessed reference, usually a hash reference. With Moose, this is an opaque thing which has a bunch of attributes and methods, as defined by its class.
  • Immutabilization Moose comes with a feature called "immutabilization". When you make your class immutable, it means you're done adding methods, attributes, roles, etc. This lets Moose optimize your class with a bunch of extremely dirty in-place code generation tricks that speed up things like object construction and so on. ๐Ÿ”ฅ

๐Ÿ”ฎ META WHAT? ๐Ÿ”ฎ

A metaclass is a class that describes classes. With Moose, every class you define gets a meta() method. The meta() method returns a Moose::Meta::Class object, which has an introspection API that can tell you about the class it represents. ๐Ÿซถ

my $meta = User->meta();

for my $attribute ( $meta->get_all_attributes ) {
    print $attribute->name(), "\n";

    if ( $attribute->has_type_constraint ) {
        print "  type: ", $attribute->type_constraint->name, "\n";
    }
}

for my $method ( $meta->get_all_methods ) {
    print $method->name, "\n";
}

Almost every concept we defined earlier has a meta class, so we've got Moose::Meta::Class, Moose::Meta::Attribute, Moose::Meta::Method, Moose::Meta::Role, Moose::Meta::TypeConstraint, Moose::Meta::Instance, and so on. โœจ

๐ŸŒˆ BUT I NEED TO DO IT MY WAY! ๐ŸŒˆ

Okay bestie, here's the tea: one of the genuinely iconic things about Moose is that if you dig down deep and discover it's doing something the "wrong way", you can just... change it. By extending a metaclass. That's it. That's the power.

Like, for real for real, you can have arrayref based objects, you can make your constructors strict (no unknown parameters allowed, not even one, we're serious ๐Ÿ’€), you can define a naming scheme for your attribute accessors, you can make a class a Singleton, and honestly much, much more.

And the wild part? Many of these extensions require surprisingly small amounts of code. And once you've done it once, you'll never have to hand-code "your way of doing things" ever again. You just load your favorite extensions and go. Periodt. ๐Ÿ’…

package MyWay::User;

use Moose;
use MooseX::StrictConstructor;
use MooseX::MyWay;

has ...;

๐Ÿ’ซ WHAT NEXT? ๐Ÿ’ซ

So you're sold on Moose. Amazing. Slay. Now it's time to actually learn how to really use it.

If you wanna see how Moose would translate directly into old school Perl 5 OO code, go check out Moose::Manual::Unsweetened. This one is genuinely helpful for quickly wrapping your brain around some aspects of "the Moose way". Lowkey a brain-glue moment, ngl.

Orrr you can skip that entirely and jump straight to Moose::Manual::Classes plus the rest of the Moose::Manual. Main character energy, no detours. โœจ

After that, we recommend you start with the Moose::Cookbook. If you work your way through all the recipes under the basics section, you should have a pretty good sense of how Moose works, and all of its basic OO features. That's the vibe check. ๐Ÿซถ

Then, after that, check out the Role recipes. And if you're really curious, go on and read the Meta and Extending recipes โ€” but just so you know, those are mostly there for people who want to be Moose wizards and extend Moose itself. ๐Ÿง™โ€โ™€๏ธ


๐Ÿ‘‘ AUTHORS ๐Ÿ‘‘

The absolute legends who made this happen, in order, every single one:

  • 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>

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. So like, go wild, but respectfully. ๐Ÿฆ‹


And that's the whole page, bestie!! ๐ŸŽ€ This lil' slice of documentation came from perl v5.42.0, dated 2025-07-25, filed under Moose::...Concepts(3). Thanks for reading the whole thing with me, you ate that. ๐Ÿ’–โœจ

๐Ÿ“ฆ where this page comes from