Bastiaan has asked for the wisdom of the Perl Monks concerning the following question:

On a circular linked list, when the 2nd last element is deleted thus the last element is pointing to itself.

(simplified code)

$var = \$var;
If I am not mistaken this situation where the ref will never get freed even after it becomes out of scope. Please confirm?

Greets,
Bastiaan

Replies are listed 'Best First'.
Re: Q on $var = \$var;
by ikegami (Patriarch) on Apr 28, 2005 at 19:17 UTC

    Yes. $var = undef breaks the loop and allow it to be freed.

    A trick is to have an object that manages (contains, provides access to) the nodes, but isn't referenced by any of the nodes. Since there's only one reference to the manager, its DESTROY will be called when it goes out of scope, and it can break any references in the list.

Re: Q on $var = \$var;
by japhy (Canon) on Apr 29, 2005 at 00:03 UTC
    You can use weak references and get around this problem:
    use Scalar::Util 'weaken'; # ... $self->{next} = (\$self == \$next) ? weaken(\$self) : \$next;

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
      Assigning a weakref yields a regular ref, and I think your test isn't quite right. Try (assuming $self/$next are references):
      $self->{next} = $next; weaken($self->{next}) if $self == $next;
      But that doesn't help with a longer circular chain; you need to pick the one element of the chain that has an external reference and weaken the preceding element's pointer to it.