Here are a couple of slick new tools that make it easy to find circular references in your Perl structures that foul up Perl's reference counting.
Lincoln Stein just released Devel::Cycle the other day, and I just noticed it today. It checks a given reference for circular references (what Lincoln calls "memory cycles"), and thus memory leaks. "What a great tool," I thought, "I'll make a Test:: module out of it!" So I just now released the 0.01 version of Test::Memory::Cycle. I named it in the Test::Memory:: namespace in planning for future memory-testing modules.
The two work together really well. For instance, WWW::Mechanize has always been plagued with circular references. It keeps a queue of pages that have been visited, implemented with references back to prior objects. I'd sure like some way to verify that I haven't fouled anything. So I started adding memory_cycle_ok() calls in the t/*.t files, like so:
my $agent = WWW::Mechanize->new();
isa_ok( $agent, "WWW::Mechanize" );
# ... do a whole bunch of Mech testing
# and then at the end ...
SKIP: {
eval "use Test::Memory::Cycle";
skip "Test::Memory::Cycle not installed", 1 if $@;
memory_cycle_ok( $agent, "No memory cycles found" );
}
The output format is pretty cool, too, if I do say so myself. Here's some sample memory cycle-creating code:
my $me = {
name => "Andy Lester",
mother => $mom,
};
$mom->{son} = $me;
my $quinn = {
name => "Quinn Lester",
father => $me,
grandmother => $mom,
};
$mom->{grandchild} = [ $quinn ];
In Lincoln's module, you run find_cycle($me) and it prints to standard output:
Cycle (2):
HASH(0x8004a0)->{mother} => HASH(0x800368)
HASH(0x800368)->{grandchild} => ARRAY(0x804c6c)
ARRAY(0x804c6c)->[0] => HASH(0x8049f0)
HASH(0x8049f0)->{father} => HASH(0x8004a0)
Cycle (3):
HASH(0x8004a0)->{mother} => HASH(0x800368)
HASH(0x800368)->{son} => HASH(0x8004a0)
In mine, you call memory_cycle_ok($me) and it prints in the test diagnostic:
I'm hoping that'll make debugging easier.
As always, your comments and suggestions are welcome!
%A->{mother}
Maybe change that too:
$A{mother}
-sam