my %dependencies = ( item1 => [ 'item2' ], item2 => [ qw' item3 item4 ' ], ); my %done; sub act_on { my $item = shift; $done{$item} = undef; # mark it early to avoid circular dependencies if (exists $dependencies{$item}) { foreach my $dep (@{$dependencies{$item}}) { warn "Circular dependency $item => $dep" if exists $done{$dep} and !$done{$dep}; &act_on($dep) unless exists $done{$dep}; } } # Dependencies satisfied, do whatever on $item print "Doing $item...\n"; $done{$item} = 1; # really done } act_on "item1"; Doing item3... Doing item4... Doing item2... Doing item1...