|P is for Practical|
The correct solution to this problem is to enhance Class::Multimethods to handle it correctly. ;-)
The problem boils down to the fact that the first argument passed to any Perl 5 constructor is the name of the class on which the constructor was called.
So, in effect, every constructor multimethod has to have '$' as the type specifier for its first parameter. Which leaves no way to tell them apart.
But there's no reason that a multiple dispatch system has to restrict itself to considering just the types of the arguments on which it's dispatching. An obvious extension is to allow the dispatcher to examine the values of those parameters and differentiate on that basis too.
Suppose, for example, that we were to generalize Class::Multimethods so that parameters could also be specified as a subroutine. When such a variant was considered in the dispatch process, instead of working out the inheritance distance from the argument's class to the parameter class, Class::Multimethods would pass the argument to the subroutine, and use the sub's return value as the distance (with undef indicating type incompatibility).
Then one could set up subroutine generators for just about any kind of dispatch criterion. For example:
Then we would be able to code class constructors as multimethods, like so:
Of course, we could simplify that even further by providing a subroutine generator that specifically compared argument values against the name of the current class:
With which we could code multiply dispatched constructors like so:
Now, if only I had the tuits to actually make Class::Multimethods work that way! :-(
Ah well...at least I can put it at the top of the module's ToDo list.