NAME
Attribute::Default - Perl extension to assign default values to subroutine arguments
SYNOPSIS
package MyPackage;
use base 'Attribute::Default';
# Makes person's name default to "Jimmy"
sub introduce : Default("Jimmy") {
my ($name) = @_;
print "My name is $name\n";
}
# prints "My name is Jimmy"
introduce();
# Make age default to 14, sex default to male
sub vitals : Default({age => 14, sex => 'male'}) {
my %vitals = @_;
print "I'm $vitals{'sex'}, $vitals{'age'} years old, and am from $vitals{'location'}\n";
}
# Prints "I'm male, 14 years old, and am from Schenectady"
vitals(location => 'Schenectady');
DESCRIPTION
You've probably seen it a thousand times: a subroutine begins with a complex series of defined($blah) or $blah = 'fribble'
statements designed to provide reasonable default values for optional parameters. They work fine, but every once in a while one wishes that perl 5 had a simple mechanism to provide default values to subroutines.
This module attempts to fill that gap.
SIMPLE DEFAULTS
If you would like to have a subroutine that takes three parameters, but the second two should default to 'Mister Morton' and 'walked', you can declare it like this:
package WhateverPackage;
use base 'Attribute::Default';
sub what_happened : Default(undef, 'Mister Morton', 'walked down the street') {
my ($time, $subject, $verb) = @_;
print "At $time, $subject $verb\n";
}
and $subject
and $verb
will automatically be filled in when someone calls the what_happened()
subroutine with only a single argument.
# prints "At 12AM, Mister Morton walked down the street"
what_happened('12AM');
# prints "At 3AM, Interplanet Janet walked down the street"
what_happened('3AM', 'Interplanet Janet');
# prints "At 6PM, a bill got passed into law"
what_happened('6PM', 'a bill', 'got passed into law');
# prints "At 7:03 PM, Mister Morton grew flowers for Perl"
what_happened("7:03 PM", undef, "grew flowers for Perl");
You can also use the default mechanism to handle the named parameter style of coding. Just pass a hash reference as the value of Default()
, like so:
package YetAnotherPackage;
use base 'Attribute::Default';
sub found_pet : Default({name => 'Rufus Xavier Sarsaparilla', pet => 'kangaroo'}) {
my %args = @_;
my ($first_name) = split(/ /, $args{'name'}, 2);
print "$first_name found a $args{'pet'} that followed $first_name home\n";
print "And now that $args{'pet'} belongs...\n";
print "To $args{'name'}.\n\n";
}
# Prints "Rufus found a kangaroo that followed Rufus home"...
found_pet();
# Prints "Rafaella found a kangaroo that followed Rafaella home"...
found_pet(name => 'Rafaella Gabriela Sarsaparilla');
# Or...
found_pet(name => 'Rafaella Gabriela Sarsaparilla', pet => undef);
# Prints "Albert found a rhinoceros that followed Albert home"...
found_pet(name => 'Albert Andreas Armadillo', pet => 'rhinoceros');
DEFAULTING REFERENCES
If you prefer to pass around your arguments as references, rather than full lists, Attribute::Default can accomodate you. Simply use Defaults()
instead of Default()
, and your reference parameters will have defaults added wherever necessary. For example:
package StillAnotherPackage;
use base 'Attribute::Default';
sub lally : Defaults({part_of_speech => 'adverbs', place => 'here'}, 3) {
my ($in, $number) = @_;
print join(' ', ('lally') x $number), ", get your $in->{part_of_speech} $in->{'place'}...\n";
}
# Prints "lally lally lally, get your adverbs here"
lally();
# Prints "lally, get your nouns here"
lally({part_of_speech => 'nouns'}, 1);
If an argument reference's type does not match an expected default type, then it is passed along without any attempt at defaulting.
DEFAULTING METHOD ARGUMENTS
If you are performing object-oriented programming, you can use the :method
attribute to mark your function as a method. The Default()
and Defaults()
attributes ignore the first argument (in other words, the 'type' or 'self' argument) for functions marked as methods. So you can use Default()
and Defaults()
just as for regular functions, like so:
package Thing;
use base 'Noun';
sub new :method :Default({ word => 'train' }) {
my $type = shift;
my %args = @_;
my $self = [ $args->{'word'} ];
bless $self, $type;
}
sub make_sentence :method :Default('to another state') {
my $self = shift;
my ($phrase) = @_;
return "I took a " . $self->[0] . " $phrase"
}
# prints "I took a train to another state"
my $train = Noun->new();
print $train->make_sentence();
# prints "I took a ferry to the Statue of Liberty"
my $ferry = Noun->new( word => 'ferry' );
print $ferry->make_sentence('to the Statue of Liberty');
BUGS
An alpha module; may change. Based on (The) Damian Conway's Attribute::Handlers, so shares whatever bugs may be found there.
AUTHOR
Stephen Nelson, <steven@jubal.com>
SPECIAL THANKS TO
Randy Ray, jeffa, and my brother and sister monks at www.perlmonks.org.