Additionally, be aware that Perl does not do lisp-style
garbage collection; it just counts references.
Consequently, if your data structure has any circular
references (such as child objects that keep a reference
back to their parents), letting them pass out of scope
and clearing your variables that point to the whole
structure won't do the trick. You have to walk the
structure and undo the links from both ends. For
example...
{ # WRONG:
my @queue = ();
foreach (@_) {
my ($a, $b, $ch) = /(\d*)[:]([^:])[:](.*?)$/;
my %parent = (a => $a, b => $b);
my @children = map
{ my ($d, $e, $f) = split /:/, $_;
my %c = (d=>$d, e=>$e, f=>$f,
p=>\%parent);
\%c; } split /,/, $ch;
$parent{children}=\@children;
push @queue, \%parent;
}
while (pop @queue) {
do_stuff($_);
}
# The item that was popped off the queue now is out of scope,
# but its children point back to it, so it stays in memory.
}
# Now the whole queue is out of scope, but the items formerly
# in it are still in memory, even now -- and there's no way
# to get back to them and free them, because you've lost
# track of all the references, even though they still exist.
{ # BETTER:
my @queue = ();
foreach (@_) {
my ($a, $b, $ch) = /(\d*)[:]([^:])[:](.*?)$/;
my %parent = (a => $a, b => $b);
my @children = map
{ my ($d, $e, $f) = split /:/, $_;
my %c = (d=>$d, e=>$e, f=>$f,
p=>\%parent);
\%c; } split /,/, $ch;
$parent{children}=\@children;
push @queue, \%parent;
}
while (pop @queue) {
do_stuff($_);
foreach (@{$$_{children}}) {
$$_{p}=undef; # child no longer has reference to parent.
}
undef $_; # Now there are zero references to the item,
# so it does go away, taking with it its
# ch key and the anon array that is its
# value, which drops the refcount to each
# element of that array to zero, causing
# them to be freed, which in turn frees
# each of the children -- I think.
}
}
This is only your problem if you have any structures
that point to eachother possibly forming a cycle of
references. (The simplest case is pairs of mutually-
referenced objects as above, but cases where a holds
a ref to b that holds a ref to c that holds a ref to
d that holds a ref to a will do the same thing.)
for(unpack("C*",'GGGG?GGGG?O__\?WccW?{GCw?Wcc{?Wcc~?Wcc{?~cc'
.'W?')){$j=$_-63;++$a;for$p(0..7){$h[$p][$a]=$j%2;$j/=2}}for$
p(0..7){for$a(1..45){$_=($h[$p-1][$a])?'#':' ';print}print$/}
|