$key = 'a.b.c.d'; @list = split /\./, $key; my %hash; my $ref = \%hash; foreach (@list[0..$#list-2]) { $ref = $ref->{$_} ||= {}; } $ref->{$list[-2]} = $list[-1]; use Data::Dumper; print Dumper \%hash;