Problem shown below:
use 5.036; # signatures
use strictures;
package Foo {
use Moose;
sub quux($self) { ... }
}
package Big::Quux {
use Moose::Role;
sub quux($self, $another) { ... }
}
package Bar {
use Moose;
extends 'Foo';
with 'Big::Quux';
}
package main {
my $class = rand > .5 ? 'Foo' : 'Bar';
say $class;
$class->quux();
# risks "Too few arguments for subroutine 'Big::Quux::quux' (got 1; expected 2)"
$class->quux('something quuxable');
# risks "Too many arguments for subroutine 'Foo::quux' (got 2; expected 1)"
}
Thus, I need to call quux
with appropriate arguments depending on its signature/arity. The class is known at runtime, and $class->can('quux')
handles inheritance correctly and provides the correct coderef. This introspection is straight-forward and painless in Kavorka, but how do I do that in plain Perl/Moose? I tried $class->meta->find_all_methods_by_name('quux')
, but that seems to be a dead end.
You have two classes providing different interfaces. You need to use the interface that's appropriate for the class, so you write different code for the different classes.
if ( $class->DOES( Big::Quux:: ) ) {
$class->quux( 'something quuxable' );
} else {
$class->quux();
}