Subroutines that take more than a single argument should really be using something like MooseX::Params::Validate.


sub vivisect { 
    my ( $self, $args ) = @_;
    confess 'Expected a hashref of arguments' unless 'HASH' eq ref $args;

    my $hamster = $args->{hamster};

OK, so we know it accepts a hashref of arguments, and what's more, we know one of them is called hamster. But: what constitutes an acceptable hamster? What do we want to do if we don't have a hamster? What other arguments am I going to need? All of this is mental load at 7am and sure, maybe there's documentation, but maybe the intern snuck in some new options and didn't tell anyone...

Compare and contrast this to:

sub vivsect {
      my ( $self, %params ) = validated_hash( \@_,
          hamster => { isa => 'Hamster', default => sub { Hamster->animate(), } },

Yes, it's some more typing. But now, as a reader, I know what's what. I know a hamster is optional, and I know what'll happen if I don't include it. I know no-one else has been adding other options like guinea_pig, because they'd show up there.

1 Comment

Many of the method signature modules on CPAN also allow type checking for arguments.

use v5.14;
use MooseX::DeclareX;
class Animal
	build name returns (Str) {
		state %count;
		my $class  = ref($self);
		my $number = ++$count{$class};
		return "$class $number";
class Hamster extends Animal;
class Laboratory
	method vivisect (Animal :$subject?) {
		$subject ||= Hamster->new;
		say "Slicing ", $subject->name;
my $lab = Laboratory->new;
my $ed  = Hamster->new(name => 'Edward');
$lab->vivisect(subject => $ed);

Leave a comment

About Peter Sergeant

user-pic I blog about Perl.