#!/usr/bin/perl use strict; use warnings; my %tree = ( FOO => [qw/BAR BLAH ASDF/], BAR => [qw/LA/], BLAH => [qw/XYZ/], ASDF => [qw/OOOOO/], LA => [], XYZ => [qw/LA/], OOOOO => [] ); { my %seen; my %onstack; my @list; sub how_to_uninstall { my $target = shift; ### COMMENT OUT THE FOLLOWING LINE ### # (@list, %seen, %onstack) = (); print "HOWTO ($target) START\n"; _traverse($target); ### NEW STUFF ### for my $token (keys(%tree)) { for (@{$tree{$token}}) { if (defined($seen{$_}) != 1) { how_to_uninstall($token); } } } ### END NEW STUFF ### print "HOWTO ($target) FINISH\n"; return @list; } sub _traverse { my $x = shift; print " TRAVERSE ($x) START\n"; $seen{$x} = $onstack{$x} = 1; for my $y (@{$tree{$x}}) { die "cyclic!" if $onstack{$y}; # back edge print " Found $y\n"; _traverse($y) unless $seen{$y}; } push @list, $x; $onstack{$x} = 0; print " TRAVERSE ($x) FINISH\n"; } } my @order = how_to_uninstall('BLAH'); print "\nANSWER = @order\n";