Devel-FindRef

 view release on metacpan or  search on metacpan

FindRef.pm  view on Meta::CPAN

   +- referenced by REF(0x7cc558) [refcount 1], which is
   |  the member 'ukukey2' of HASH(0x7ae140) [refcount 2], which is
   |     +- referenced by REF(0x8abad0) [refcount 1], which is
   |     |  the lexical '$testsub_local' in CODE(0x8ab430) [refcount 3], which was seen before.
   |     +- referenced by REF(0x8ab4f0) [refcount 1], which is
   |        the global $Test::global_hashref.
   +- referenced by REF(0x7ae518) [refcount 1], which is
   |  the member 'ukukey' of HASH(0x7d3bb0) [refcount 1], which is
   |     the global %Test::global_hash.
   +- referenced by REF(0x7ae2f0) [refcount 1], which is
      a temporary on the stack.

It is a bit convoluted to read, but basically it says that the value
stored in C<$var> is referenced by:

=over 4

=item - the lexical C<$closure_var> (0x8abcc8), which is inside an instantiated
closure, which in turn is used quite a bit.

=item - the package-level lexical C<$global_my>.

=item - the global package variable named C<$Test::var>.

=item - the hash element C<ukukey2>, in the hash in the my variable
C<$testsub_local> in the sub C<Test::testsub> and also in the hash
C<$referenced by Test::hash2>.

=item - the hash element with key C<ukukey> in the hash stored in
C<%Test::hash>.

=item - some anonymous mortalised reference on the stack (which is caused
by calling C<track> with the expression C<\$var>, which creates the
reference).

=back

And all these account for six reference counts.

=head1 EXPORTS

None.

=head1 FUNCTIONS

=over 4

=item $string = Devel::FindRef::track $ref[, $depth]

Track the perl value pointed to by C<$ref> up to a depth of C<$depth> and
return a descriptive string. C<$ref> can point at any perl value, be it
anonymous sub, hash, array, scalar etc.

This is the function you most likely want to use when tracking down
references.

=cut

sub find($);

sub _f($) {
   "$_[0] [refcount " . (_refcnt $_[0]) . "]"
}

sub track {
   my ($ref, $depth) = @_;
   @_ = ();

   my $buf = "";
   my %seen;

   Scalar::Util::weaken $ref;

   my $track; $track = sub {
      my ($refref, $depth, $indent) = @_;

      if ($depth) {
         my (@about) = find $$refref;
         if (@about) {
            for my $about (@about) {
               $about->[0] =~ s/([^\x20-\x7e])/sprintf "\\{%02x}", ord $1/ge;
               $buf .= "$indent" . (@about > 1 ? "+- " : "") . $about->[0];
               if (@$about > 1) {
                  if ($seen{ref2ptr $about->[1]}++) {
                     $buf .= " " . (_f $about->[1]) . ", which was seen before.\n";
                  } else {
                     $buf .= " " . (_f $about->[1]) . ", which is\n";
                     $track->(\$about->[1], $depth - 1, $about == $about[-1] ? "$indent   " : "$indent|  ");
                  }
               } else {
                  $buf .= ".\n";
               }
            }
         } else {
            $buf .= "$indent   not found anywhere I looked :(\n";
         }
      } else {
         $buf .= "$indent   not referenced within the search depth.\n";
      }
   };

   $buf .= (_f $ref) . " is\n";

   $track->(\$ref, $depth || $ENV{PERL_DEVEL_FINDREF_DEPTH} || 10, "");
   $buf
}

=item @references = Devel::FindRef::find $ref

Return arrayrefs that contain [$message, $ref] pairs. The message
describes what kind of reference was found and the C<$ref> is the
reference itself, which can be omitted if C<find> decided to end the
search. The returned references are all weak references.

The C<track> function uses this to find references to the value you are
interested in and recurses on the returned references.

=cut

sub find($) {
   my ($about, $excl) = &find_;



( run in 0.798 second using v1.01-cache-2.11-cpan-5b529ec07f3 )