This refactoring of your code works fine. I have rewritten process
to do all that is necessary for the innermost hashes. I have named these $item
as I don't know what they are supposed to represent. Please amend this to something more descriptive.
There never was any reason to pass all those parameters, as the values of $description
, $mod
, and $index
were only used to locate the hash in question using $description->{$mod}[$index]
so it may as well have been passed directly as a reference, which is what I do. In addition, because process
now loops over the array contents there is no need to pass $key
either, so the subroutine now has just one parameter.
Each element of $item
is examined, and the new hash of data to be added for that element is obtained from function1
or function2
as appropriate and pushed onto @params
instead of being inserted straight away.
Once all the new values have been established, they are all added into $item
and the process is complete.
for my $defined (values %$description) {
process($_) for @$defined;
}
sub process {
my ($item) = @_;
my @params;
for my $key (keys %$item) {
push @params, $key eq 'keyword' ? function1() : function2();
}
for my $params (@params) {
@{$item}{keys %$params} = values %{$params};
}
}