in reply to parsing a parent-child syntax to make a hash

First of all, you can easily dump structures using Data::Dumper. No need to roll out your custom subroutine.

You can do some complicated dereferencing/referencing:

use strict; use warnings; my $str = "One:Two:Three:four, One:Two:3:4, One:2:3:4, One:2:three"; my %hash; my @defs = split(/\s*,\s*/, $str); # Use Text::CSV? foreach my $def (@defs) { my @keys = split(/:/, $def); my $val = pop(@keys); my $p = \\%hash; while (@keys) { $p = \($$p->{shift(@keys)}); } $$p = $val; } require Data::Dumper; print(Data::Dumper::Dumper(\%hash));

Or you can use tye's Data::Diver module:

use strict; use warnings; use Data::Diver qw( DiveVal ); my $str = "One:Two:Three:four, One:Two:3:4, One:2:3:4, One:2:three"; my %hash; my @defs = split(/\s*,\s*/, $str); # Use Text::CSV? foreach my $def (@defs) { my @keys = split(/:/, $def); my $val = pop(@keys); DiveVal(\%hash, map { \$_ } @keys) = $val; } require Data::Dumper; print(Data::Dumper::Dumper(\%hash));

The second snippet is untested.

Important! The first snippet doesn't check for bad data such as 'one:orange, one:apple:car', but it would be easy to add a check. I don't know how Data::Diver deals with that.