It uses trickery from the Scalar::Util module. There were a lot of gotchas involved -- avoiding autovivification and avoiding strengthening weak references by copying. Limitations are that you've got to pass a closure and create the object in that. And it's totally destructive (at least it is when the test is successful). Anything returned by the closure is potentially (and hopefully) gone forever.
in reply to Re: A way to test that circular references are actually freed
in thread A way to test that circular references are actually freed
Perhaps the most severe limitation is that it can't have references to any globals or any memory which is supposed to hang around -- it's not smart about that, but just assumes everything must go. If there's interest I may in a future version allow the caller to specify exceptions
The basic trick is to create weak references to the strong references and strong references to the weak references, free up the base reference, and see if all the others go to undefined. I've just added some code to make it smart about undefs in the original object.
I'll get it on CPAN in a couple of days, and you'll be able to read the code. It's not long.