Devel::Refcount(3pm)

✨ Devel::Refcount ✨

okay bestie so this is a page from the User Contributed Perl Documentation for the module Devel::Refcount, and it's genuinely one of my faves because it lets you see how many things are holding onto your data 🫢 like a little x-ray for your references, fr fr.


πŸ’– NAME πŸ’–

Devel::Refcount β€” obtain the REFCNT value of a referent

like. it tells you how many refs are pointing at the thing. that's it. that's the whole vibe. πŸ‘‘


🌟 SYNOPSIS 🌟

use Devel::Refcount qw( refcount );

my $anon = [];

print "Anon ARRAY $anon has " . refcount( $anon ) . " reference\n";

my $otherref = $anon;

print "Anon ARRAY $anon now has " . refcount( $anon ) . " references\n";

assert_oneref $otherref; # This will throw an exception at runtime

see that last line? yeah, that one will throw at runtime, that's not a drill 😭 it's literally there to show you what a failed assertion looks like.


🌸 DESCRIPTION 🌸

This module gives you one single function that grabs the reference count of whatever object your reference value is pointing at. That's it. One function. Live your life. ✨

It also gives you a debugging assertion, assert_oneref, which asserts that a given reference has a count of only 1. so if something's still hanging around when it shouldn't be, it will absolutely call it out πŸ’…


πŸŽ€ FUNCTIONS πŸŽ€

🌈 $count = refcount( $ref )

Returns the reference count of the object being pointed to by $ref. straightforward. iconic. no notes.

🌈 assert_oneref( $ref )

Asserts that the given object reference has a reference count of only 1.

  • If that's true β†’ the function does absolutely nothing. good vibes only. πŸ¦‹
  • If it has more than 1 reference β†’ an exception is thrown. πŸ’€
  • Bonus: if Devel::FindRef is available, it gets used to print a more detailed trace of where all those references are hiding. like a little detective πŸ•΅οΈβ€β™€οΈ

Typically this is useful in debugging, to track down cases where objects are still being referenced past the point where they were supposed to be dropped. For example, if an element is deleted from a hash and that ought to be the last remaining reference, you can assert on the return value of the delete operator:

assert_oneref delete $self->{some_item};

If there are any other references to this object at the time of deleting, the assertion fails, and if Devel::FindRef is available, those other locations get printed for you. main character debugging energy, honestly. πŸ”₯


πŸ’œ COMPARISON WITH SvREFCNT πŸ’œ

okay so the way this differs from Devel::Peek::SvREFCNT is:

  • SvREFCNT() gives you the reference count of the SV object itself that you passed in.
  • refcount() gives you the count of the object being pointed to.

which means refcount() can give you the count of any referent β€” like ARRAY, HASH, CODE, GLOB and Regexp types. it's giving versatile. πŸ‘‘

Consider this example program:

use Devel::Peek qw( SvREFCNT );
use Devel::Refcount qw( refcount );

sub printcount
{
   my $name = shift;

   printf "%30s has SvREFCNT=%d, refcount=%d\n",
      $name, SvREFCNT( $_[0] ), refcount( $_[0] );
}

my $var = [];

printcount 'Initially, $var', $var;

my $othervar = $var;

printcount 'Before CODE ref, $var', $var;
printcount '$othervar', $othervar;

my $code = sub { undef $var };

printcount 'After CODE ref, $var', $var;
printcount '$othervar', $othervar;

This produces the output:

                Initially, $var has SvREFCNT=1, refcount=1
          Before CODE ref, $var has SvREFCNT=1, refcount=2
                      $othervar has SvREFCNT=1, refcount=2
           After CODE ref, $var has SvREFCNT=2, refcount=2
                      $othervar has SvREFCNT=1, refcount=2

so here's what's actually happening, bestie:

SvREFCNT() counts the number of references to the SV object passed in as the scalar value β€” so that's $var or $othervar respectively. Meanwhile refcount() counts the number of reference values that point to the referent object β€” which in this case is the anonymous ARRAY. 🧚

Before the CODE reference is constructed, both $var and $othervar have an SvREFCNT() of 1, because they exist only in the current lexical pad. The anonymous ARRAY has a refcount() of 2, because both $var and $othervar store a reference to it.

After the CODE reference is constructed, $var now has an SvREFCNT() of 2, because it also appears in the lexical pad for the new anonymous CODE block. see? it all adds up. no cap. ✨


πŸ¦‹ PURE-PERL FALLBACK πŸ¦‹

An XS implementation of this function is provided, and it's used by default. If the XS library cannot be loaded, a fallback implementation in pure perl using the B module is used instead.

It will behave identically β€” but it is much slower. so like, same energy, way less speed. πŸ™ˆ
        Rate   pp   xs
pp 225985/s   -- -66%
xs 669570/s 196%   --

so yeah, xs is absolutely eating πŸ’…


🌈 SEE ALSO 🌈

  • Test::Refcount β€” assert reference counts on objects

🫢 AUTHOR 🫢

Paul Evans <leonerd@leonerd.org.uk>


okay that's the whole page, you're literally a reference-counting expert now, periodt πŸ’–

and for the cute sign-off: this was rendered out of perl v5.42.3, dated 2026-08-19, and the page itself is Devel::Refcount(3pm) β€” go forth and count your refs, my love πŸŽ€βœ¨

πŸ“¦ where this page comes from