# Multiple Return Value concept code use strict; use warnings; use Carp; sub _populate_hash { my $hash= shift; my @values= @{shift(@_)}; my @names= @{shift(@_)}; croak unless scalar @values == scalar @names; while (@values) { $hash->{shift @names}= shift @values; } } sub create_multiple_return # call this from the function you want to work this way. { my $retlist= shift; # first parameter is list ref of all values my $namelist= shift; # second parameter is list of names of those values my $wantnames; # remaining arg list is what caller supplied on the host function: # either hash ref, list ref, or individual strings, or empty. ### (1) call with no args to return entire list. return @$retlist unless @_; my $paramtype= ref $_[0]; ### (2) call with hash ref populates the hash. if ($paramtype eq 'HASH') { _populate_hash ($_[0], $retlist, $namelist); return; } my %vals; _populate_hash (\%vals, $retlist, $namelist); ### (3) call with individual strings, make look same as case 4. unless ($paramtype) { # scalar $wantnames= \@_; } else { ### (4) list of value names to return $wantnames= shift; croak unless ($paramtype eq 'ARRAY'); carp "too many params" if @_; } return map { croak unless exists $vals{$_}; $vals{$_} } @$wantnames; } ############# # example data { my @namelist= qw/year month day hour minute second/; my @vallist= qw/2001 July 10 1 2 30/; sub get_time { my $ignored_argument= shift; return create_multiple_return (\@vallist, \@namelist, @_); } } my $Param= 5; # show how IN parameters are before the stuff this module deals with. my @A= get_time($Param); # (1) get all return values in pre-defined order. print "@A\n"; @A= get_time ($Param, qw/second year hour/); # (3) specify list of desired values, in desired order. print "@A\n"; my @wantnames= qw/month year/; @A= get_time ($Param, \@wantnames); # (4) single ref to list instead of individual params print "@A\n"; my %hash; get_time ($Param, \%hash); # (2) populate hash foreach (keys %hash) { print "$_ => $hash{$_} "; } print "\n";