indeed. cyclic references *can* be a bitch though, especially in situations where one has a lot of inter-operating objects in a persistent Perl interpreter, eg mod_perl. consider:
#!/usr/bin/perl -w
use strict;
package A;
{
sub new {
my $class = shift;
return bless( { @_ }, $class );
}
sub DESTROY {
warn "$_[0] just died";
}
sub set {
$_[0]->{ $_[1] } = $_[2];
}
}
package B;
{
@B::ISA = qw/ A /;
}
package C;
{
@C::ISA = qw/ A /;
}
package main;
warn "doing something...\n";
do_something();
warn "doing something else (again)...\n";
do_something();
warn "exiting program...\n";
exit;
sub do_something {
warn "entering block...\n";
my $a = new A ();
my $b = new B ();
my $c = new C ();
$b->set( C => $c );
$c->set( B => $b );
warn "exiting block\n";
}
# output of above:
doing something...
entering block...
exiting block...
A=HASH(0x804b424) just died at ./test_objects.pl line 13.
doing something else (again)...
entering block...
exiting block...
A=HASH(0x805d074) just died at ./test_objects.pl line 13.
exiting program...
C=HASH(0x805bb10) just died at ./test_objects.pl line 13 during global
+ destruction.
B=HASH(0x805b9f0) just died at ./test_objects.pl line 13 during global
+ destruction.
C=HASH(0x805d08c) just died at ./test_objects.pl line 13 during global
+ destruction.
B=HASH(0x804b424) just died at ./test_objects.pl line 13 during global
+ destruction.
Voila, an unclaimed cyclic reference every time you call do_something(), or any other code that creates object that store references to each other. This is surprisingly easy to do in a large, multi object/reference system, and irritatingly difficult to track down when it happens. meanwhile, your httpd's are growing and growing with every page request....
matt
|