use Data::Dumper; package Foo::Empty; package Foo::OneVar; $one_var = 'foo!'; package main; my %done; sub seek_destroy { my ( $name ) = @_; return if $done{$name}++; foreach my $package ( grep { /::$/ } keys %{$name} ) { print "$name$package\n"; print "!!! $name$package" . "DESTROY!!\n" if exists ${"$name$package"}{DESTROY}; seek_destroy( "$name::$package" ) if defined $package; } } seek_destroy( 'main::' );