Each object has a meta object which can be used to describe and sometimes alter the object. This is for things which are common to *all* objects. For example, $obj->mc->class to get the object's class. @ISA = $obj->mc->ISA to get an object's parents. And so on.

Why not just stick these methods in UNIVERSAL? They'd clash with user-space methods. For example, if an existing class has its own id() method it would likely clash with what our id() method does. You want to guarantee that every object responds to these meta methods the same way so there's no second-guessing.

Each object has a meta object for their instance, accessible with $obj->mo and also a meta object for their class, accessible with $obj->mc. The meta instance can do most everything the meta class can, mc is provided mostly for disambiguation.

The problem is this:

my $thing = "Foo";
say $thing->mo->class;

In perl5i, everything is an object. Do you want the class of $thing or do you want to treat $thing as a class name? Its ambiguous. So to disambiguate, use $thing->mc when you mean $thing to be a class name and $thing->mo when you mean it to be an object.

For example, when writing a method which could be a class or could be an object be sure to use $proto->mc->class to get the class name.

sub my_method {
my $proto = shift; # could be an object, could be a class name
my $class = $proto->mc->class;
....
}

Two different objects can have the same checksum if their contents are identical. Likewise, a single object can have different checksums throughout its life cycle if it's mutable. This means its checksum will change if its internal state changes.