TIL - Object Method: Named Arguments Unpacking

TIL (or re-learned) how to unpack an object method that has named args, thanks to the Modern Perl book:

    my ($self, %args) = @_;

This idiom unpacks $self, then throw the rest of the arguments into %args.


I always preferred
my $self = shift;
my %args = @_;
to keep the parameters in @_
or the more paranoid (coping with named parameters in a hashref)
my $self = shift;
my %args = @_ == 1 ? %{$_[0]} : @_;
or the one that loses you points in code review
my $self = shift;
local %_ = @_;

For a couple of years now I’ve been writing the opening line of my methods as

my ( $self, ... ) = ( shift, @_ );

Of course an %args slots right in there.

The point to this two-fold.

First of all, using shift to pull the instance into $self (or $class in a class method) makes it easy to say things like $self->SUPER::foo( @_ ) where you pass along the whole “actual” @_ to some other method that’s supposed to have the same signature.

Secondly, Perl’s lack of real signatures already makes short subs/methods too painfully verbose, so the last thing we need is to make the problem even worse, and yet it’s good to have an obvious marker distinguishing methods from regular subroutines. This idiom accomplishes that without expending additional vertical space to do so.

I always preferred

my $self = shift;
my %args = @_;

because I usually do

my $self = shift;
my %args = (
param1 => "0", ## default value
param2 => undef, ## documenting

so that I can set reasonable defaults and don't have to do if exists all over the place.

Leave a comment

About Mark Leighton Fisher

user-pic Perl/CPAN user since 1992.