Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Can you determine the number of References to a value?

by shotgunefx (Parson)
on Sep 13, 2001 at 03:14 UTC ( #112053=perlquestion: print w/ replies, xml ) Need Help??
shotgunefx has asked for the wisdom of the Perl Monks concerning the following question:

I've been playing around with adding my own functions for processing arrays and such that act as built-ins.

Basically, the problem I have is they have to allocate some references to pieces of data they have been passed so they can operate within while loops,etc.

Well, by keeping references to the data, I am stopping the memory from getting garbage collected. What I would like to do if possible when these functions are called, decrement the reference count to 0 if I am the only one holding a reference to any given pieces of data that I've stored. (If the ref count is 1 for a piece of data, then I must be the only one holding onto it, correct?)

I've started looking into perlguts and such. I was wondering if anyone has any experience with this or similar.

Thanks.

-Lee

"To be civilized is to deny one's nature."

Comment on Can you determine the number of References to a value?
Re: Can you determine the number of References to a value?
by wog (Curate) on Sep 13, 2001 at 03:24 UTC
    The Devel::Peek module offers the functions SvREFCNT, SvREFCNT_inc, and SvREFCNT_dec, if you import them explictly. These can give you direct access to the refcount of objects.

    (Note that holding a reference to something, and decrementing its refcount manually is likely to cause perl to become confused -- you can probably decrement it's refcount by cleaning up all your refrences to it instead. It looked like you may have been thinking about doing something like this from your wording.)

      Thanks.
      Basically at this point, I'm doing it just to see how. What I want to do (and have done) is create a few list operators.

      elements

      returns 1 or more elements. Like so


      findone

      Like grep only returns first matching element and index. Subsequent calls return next matching element and index or undef if array is processed.

      while ( my @els = elements @array,5){ somefunc(@els). } while ( findone { $_ > 5 } @array } print "Found $_\n"; } # or while (my ($val,$index) = findone { $_ > 5 } @array } print "Found $val in position $index\n"; }

      The problem is that I want to be able to nest calls to it which means I have to keep track of the current list. By taking a reference to them, I am stopping it from getting garbaged collected. The references are stored in a hash. What I'd like to do is loop through each and see if the ref count is 1. If it is, then it has to be me and I can "I think" safely delete my reference to it.

      UPDATE
      Does anyone else see value in these constructs? I think there handy. One of the things that I love about Perl is how much you can say in so few words. I was thinking of making the eleements operator possibly take a CODEREF so thay you could grab all the elements up to and including the element that returns true.

      -Lee

      "To be civilized is to deny one's nature."

        Yes, deleting your reference when the count goes to 1 makes sense in some situations. A more efficient way to accomplish this (and more general since it allows two or more different chunks of software to do the same trick to the same data) is called a "weak reference" which is available in Perl 5.6 and later.

        A weak reference is just like an ordinary Perl reference except that it isn't included in the reference count of the thing referred to. This means that once all references to a particular piece of data are weak, the piece of data is freed and all the weak references are set to undef.

        So you just have to check your weak references to make sure they haven't become undef before you use them. See WeakRef.

                - tye (but my friends call me "Tye")
Re: Can you determine the number of References to a value?
by derby (Abbot) on Sep 13, 2001 at 03:43 UTC
    Lee,

    In addition to wog's suggestion of Devel::Peek, why not have some fun with Inline:

    #!/usr/bin/perl use Inline C; $ref = 1; $refa = \$ref; $refb = \$ref; print myrefcount( $ref ); __END__ __C__ int myrefcount( SV *a ) { return SvREFCNT( a ); }

    -derby

      Thanks!

      I've been meaning to play with inline. So much simpler than XS.

      -Lee

      "To be civilized is to deny one's nature."

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://112053]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (7)
As of 2014-12-26 23:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls