Lot's of OO modules have a param() method: CGI::Application, HTML::Template, CGI::Session... and they are mostly all about the same. That is, they are a glorifed hash wrapper.
Yet, in Perl5 it's easy for the code for them to be verbose, especiall if you want to accept both a hash /and/ a hashref, and provide some error checking on the input.
The param() method of CGI::App in Perl5 was 33 lines (including some whitespace). The Perl6 translation was 3 lines! This is possible with subroutine signatures and multi-method dispatch. Further, Perl6 tries somewhat successfully to hid e the difference between a hash and hashref, which eliminates another case to check for.
For constrast, here's the two pieces of code:
In Perl5
sub param {
my $self = shift;
my (@data) = (@_);
# First use? Create new __PARAMS!
$self->{__PARAMS} = {} unless (exists($self->{__PARAMS}));
my $rp = $self->{__PARAMS};
# If data is provided, set it!
if (scalar(@data)) {
# Is it a hash, or hash-ref?
if (ref($data[0]) eq 'HASH') {
# Make a copy, which augments the existing contents (if any)
%$rp = (%$rp, %{$data[0]});
} elsif ((scalar(@data) % 2) == 0) {
# It appears to be a possible hash (even # of elements)
%$rp = (%$rp, @data);
} elsif (scalar(@data) > 1) {
croak("Odd number of elements passed to param(). Not a valid hash");
}
} else {
# Return the list of param keys if no param is specified.
return (keys(%$rp));
}
# If exactly one parameter was sent to param(), return the value
if (scalar(@data) <= 2) {
my $param = $data[0];
return $rp->{$param};
}
In Perl6
multi method param () returns Array { %!params.keys }
multi method param (Str $key) returns Array { @( %!params{$key} ) }
multi method param (%h,*%h) { %!params = %(%!params, %h); undef }
I think the difference stands for itself.
Comments