First, read Tyler Curtis's Age discrimination in Perl 6 using subsets and multiple dispatch.
You can do everything in that post manually in Perl 5. (You're better off using a module such as MooseX::MultiMethods to handle the plumbing for you, but the point stands.) That's the fallacy of the Turing tarpit and the Blub programmer: everything is possible, but language support makes certain constructs easy and obvious, and easy and obvious code tends to exist.
If you think about Tyler's post that way, you can squint and see a general language design principle at work. Let me belabor the point somewhat more. Consider how to declare a new class in Perl 5. You have multiple possibilities. A class is merely a namespace, so:
package My::Class { ... }
That's well and good, and it works. Now do it at runtime:
eval "package $classname { ... }";
Again, that works. Yet if you consider the Class::MOP approach, you can start to see the flaw:
my $class = Class::MOP::Class->create( $classname );
I admit the flaw isn't staggeringly obvious until you need to add methods to the class. Again, it's not awful in standard Perl 5:
sub My::Class::method { ... }
... or at runtime:
{
no strict 'refs';
*{ $classname . '::' . $methname } = $method_ref;
}
... but how ugly when compared to:
$class->add_method( $methname, $method_ref );
The difference is the design principle at work: specify policy, not mechanism. In other words, the problem with the standard Perl 5 approach is that the how of how you store a subroutine in a package overshadows the intent of the approach. What's important is not symbolic references to typeglob slots in packages which represent classes. What's important is adding a method to a class.
The same rule applies when specifying type constraints on function parameters or multidispatch candidates or even declaring classes themselves:
class My::Class
{
method awesome_method { ... }
}
... because even as much as I know how to implement a language on top of a virtual machine (or how to compile a language to native code), at the point where I read this code, much less write it, I don't care about the mechanism. I care about defining the policy.