Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

The number of references to a variable

by jeanluca (Deacon)
on Nov 26, 2007 at 11:37 UTC ( [id://652958]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks

I would like to know if it is possible to retrieve the number of references to a perl variable (in my case a hash-object).
For example, I have an array of objects (each object might be referenced by something else) and I only want to use those objects which are referenced.
I was thinking about using information from the GC (which does reference counting), but I'm not sure how and also, my brethren, I'm not sure this is the right path!!?

Thnx a lot
LuCa

Update: very interesting posts (weak reference is new for me). For the problem at hand I prefer cdarke's solution. thnx again!

Replies are listed 'Best First'.
Re: The number of references to a variable
by Corion (Patriarch) on Nov 26, 2007 at 11:50 UTC

    I tought there was a function in Scalar::Util that returns the refcount of an object, but I couldn't find it. But also in Scalar::Util, you find the weaken function, which lets you pass around weak references. From your description, I think you have a "master" object that holds all "relevant" children, but over time, some of the children become irrelevant yet are kept alive by some references. If you make your master hold strong (normal) references but pass out only weak references, your children will be removed if the master removes them from the list.

    Such an approach will have different problems, because weak references can turn into strong references again if you copy them, unfortunately. Maybe another approach would be to (always) ask the master whether a child is still relevant or not ...

      I'm just curious, is the only way to make a weak reference strong, by copying it ?
      $y = \($$y) ;

      LuCa
        I wouldn't call that copying. Your snippet creates a new reference. And yes, that works.
Re: The number of references to a variable
by lima1 (Curate) on Nov 26, 2007 at 12:29 UTC
    The SvREFCNT macro (perlguts) returns this number. I am sure this is already somewhere on cpan, but a simple XS routine could look like this:
    /* generated by h2xs -c Scalar::RefCount */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" MODULE = Scalar::RefCount PACKAGE = Scalar::RefCount int refcount(s) SV* s PROTOTYPE: $ CODE: RETVAL = SvREFCNT(s); OUTPUT: RETVAL
    use Test::More tests => 6; BEGIN { use_ok('Scalar::RefCount') }; ######################### my $a; is(Scalar::RefCount::refcount($a),1, 'return 1'); my $b = \$a; is(Scalar::RefCount::refcount($a),2, 'return 2'); my $c = \$a; is(Scalar::RefCount::refcount($a),3, 'return 3'); { my $d = \$a; is(Scalar::RefCount::refcount($a),4, 'return 4'); } is(Scalar::RefCount::refcount($a),3, 'return 3');
    Update: Ah, thanks cdarke.
      SvREFCNT is exposed in Devel::Peek (no need to go to CPAN), which is a bit easier to use than embedding XS. For example:
      use Devel::Peek qw(SvREFCNT); $x = 42; $y = \$x; $refs_for_x = SvREFCNT($x); print "$refs_for_x\n";
      Prints 2.
Re: The number of references to a variable
by jbert (Priest) on Nov 26, 2007 at 11:54 UTC
    If you want objects which aren't referenced to go away, you could use store a 'weak' reference to each of your objects in your array, and the weak reference will become undef if there are no 'real' references left to the object. That might do what you need. (See Scalar::Util for weaken).

    Otherwise, it seems an unusual route to go down and that makes me think it might not be the right path. Could you let us know more about your motivation for this, so we can offer an opinion on this?

Re: The number of references to a variable
by BrowserUk (Patriarch) on Nov 26, 2007 at 17:02 UTC
Re: The number of references to a variable
by Somni (Friar) on Nov 27, 2007 at 13:34 UTC
    As has been mentioned, Devel::Peek provides an SvREFCNT. There's also a builtin function (probably undocumented) called Internals::SvREFCNT.

    Your statement:

    I only want to use those objects which are referenced
    didn't make a lot of sense, however. The only objects you have access to are those with references to them; if there are no references to an object then it is deallocated. Therefore, any refcount check would be guaranteed to be over 0.

    I simply wanted to point that out; perhaps it was just a miscommunication. If weaken was what you were looking for, great.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://652958]
Approved by Corion
Front-paged by bart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-16 10:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found