In the discussion of A Design for Class Attributes in Perl 5.16 or Perl 5.18 (along with other discussions such as Modern Perl: the book), a meta-object protocol is, effectively, a design for an object system that it itself object oriented.
In other words, you have an object which represents the class of an object. To create a new class, you might write something like:
my $class = MetaClass->new( name => 'My::Class' );
You can add methods by calling add_method()
and add attributes
by calling add_attribute()
. This is, in fact, what Class::MOP does in Perl 5,
and what Parrot provides (not well, at the moment) to Rakudo Perl 6 and other
hosted languages, and what a new MOP built for Rakudo Perl 6 does very
well.
A good MOP has at least two important properties. First, it's a consistent and coherent underlying mechanism on which to build language features. Second, it's flexible and extensible.
The latter is even more important than it sounds at first.
Moose encourages the use of well-encapsulated, opaque objects by default, while blessed hash references might as well just be hash references, as anyone can poke and prod in them anytime. (Certainly you can do the same with Moose objects, but the documentation and design of Moose discourage you from even knowing that such a thing is possible.)
If the language syntax (and I've not mentioned them before now) allow you to specify a different metaclass—something other than Class
—you can create objects with different behaviors and different storage of methods and attributes and other data trivially.
If the rest of the language, from the internals to all other extension mechanisms, interoperate in terms of the protocol of the MOP, these objects and classes and metaclasses will all behave and interoperate effectively.
In other words, if I were to propose a blue sky feature for Perl 5.16 without worrying about development resources or testing or feasibility of implementation or likelihood of merging into bleadperl, I would say this:
Beg, borrow, and steal a good MOP—perhaps the MOP from Rakudo Perl 6—and reimplement default Perl 5 OO in terms of that MOP.
Then let us discuss adding a class
keyword and a
method
keyword and syntax for declaring attributes. Let's solve
the biggest problem first: there's no reason to have multiple object systems in
the core, not if they're slightly incompatible. As a bonus, we get much better
introspection, dynamic programming, and reflection for free.
(If you're not sure how reimplementing blessed hashes in terms of a MOP makes things easier, consider this: anything which has the same duck-typed or interface-checked or, as is my wont, role-based design nature as the DefaultClass
metaclass will be substitutable in any place you'd normally use DefaultClass
, whether you use a MooseClass
metaclass or a XSFriendlyClass
metaclass or a SerializableClass
metaclass or a ThreadSafeClass
metaclass or what have you. The possibilities are... powerful.)
No matter how hard you squint, at the MOP level Perl5 and Perl6 are radically different. Perl6 is deep down a Prototype system that has a Class system built on top of it. While this is possible (see Joose for an example), it's simply not the Perl5 object system we have come to know and love. Perl5 deserves a proper explicit MOP based around the object system that has been in place for 15+ years and (for all it's warts) has served us well so far.
Certainly I'm not suggesting that the protoobject system is appropriate for Perl 5. I do like the distinction between storage representation and behavior though. That's eminently stealable. Take out the idea of protoobjects, stick with the well-known behavior of Perl 5, and you still have something good.
Yep and that roughly describes what Class::MOP already does. I think we're all on board with that.
I thought one of the problems (although I haven't been on top of this particular area of Perl) was the speed of MOP in Perl5.