my %hash; my @tests = ( [ 'string1', 'string2', 'string3', 'string4' ], [ 'string3', 'string4' ], [ 'string1', 'string2', 'string3' ], ); for my $t (@tests) { my $hr = \%hash; my @strings = @$t; increment($hr, @strings); } sub increment { my ($hr, @strings) = @_; if (@strings == 1) { # simple case ++$$hr{$strings[0]}; } else { # Peel the first string from the list my $first_string = shift @strings; # Get the associated hash reference $hr = $$hr{$first_string}; # Call ourself... increment($hr, @strings); } }