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

Is it possible to obtain all hard references to some memory address by knowing only one of them? short example:
#!/usr/bin/perl use strict; use Scalar::Util qw(refaddr); package Hmmm; sub new {bless {}, shift;} 1; my $hm = $Hmmm->new(); my $copy = $hm; # hard..
i don't know nothing about $copy (when and where it was created) but need to destroy it..
my $addr = refaddr($hm); undef $hm;
$copy still exists.. Is it possible to know about $copy from $addr or something?
  • Comment on Is it possible to obtain all hardreferences to some memory address by knowing only one of them?
  • Select or Download Code

Replies are listed 'Best First'.
Re: Is it possible to obtain all hardreferences to some memory address by knowing only one of them?
by Joost (Canon) on Feb 07, 2007 at 14:46 UTC
      How can I weaken reference ($copy in example above) if i don't know about it existence? Is it possible to obtain all references that refer to specified object?
        How do you know there are references then?

        Please explain why you'd want to do this, because you're trying to do something that you'd normally never want to do, and perl is in fact designed to stop you doing this.

        Any way, if i had to, I'd probably resort to Tie::Scalar to fake a reference and return weak-references whenever someone tries to copy it*). Very non-intuitive, slow and confusing, but at least sort of portable. Also, that way you could throw some stack-traces to STDERR to see where the **** your references get copied.

        *) now that I think about it, I'm not even sure that would work.

        Btw, what's the reason you are trying to do this? This smells like a bug in your application design to me.

        Ordinary morality is for ordinary people. -- Aleister Crowley
Re: Is it possible to obtain all hardreferences to some memory address by knowing only one of them?
by diotalevi (Canon) on Feb 07, 2007 at 16:44 UTC

    Consult sv.c about the arenas. This is where everything perl manages is managed. You'll write some C which can be used by the visit() function. That function can find your SV heads where SvANY() == your pointer. I'd guess you'd zero the refcount and call sv_clear on it then. I've included a copy of a simple function that uses visit() just so you can see how short and easy this can be.

    visit(do_report_used, 0, 0); static void do_report_used(pTHX_ SV *sv) { if (SvTYPE(sv) != SVTYPEMASK) { PerlIO_printf(Perl_debug_log, "****\n"); sv_dump(sv); } }

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      Except that isn't part of the Perl API and is subject to change, so it's not to be recommended. Also, visit() is a static function which can't be used outside of sv.c, and who's prototype has changed between 5.8.0 and 5.8.8.

      To answer the OP: no, there's no official way to achieve this.

      Dave.

        It's still a better way to accomplish this dubious goal than other ways. At least this way the infrastructure for walking this stuff is getting used. Now the OP can expect breakage between versions of perl...

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re: Is it possible to obtain all hardreferences to some memory address by knowing only one of them?
by Corion (Patriarch) on Feb 08, 2007 at 12:34 UTC

    There is Devel::FindRef, but even its documentation says This is a quick hack only. As the others already said, there is no official way.