ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Devel-FindRef/FindRef.pm
Revision: 1.1
Committed: Thu Jan 11 22:30:34 2007 UTC (17 years, 4 months ago) by root
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# Content
1 package Devel::FindRef;
2
3 use strict;
4
5 use XSLoader;
6
7
8 BEGIN {
9 our $VERSION = '0.1';
10 XSLoader::load __PACKAGE__, $VERSION;
11 }
12
13 =head1 NAME
14
15 Devel::FindRef - where is that reference to my scalar hiding?
16
17 =head1 SYNOPSIS
18
19 use Devel::FindRef;
20
21 =head1 DESCRIPTION
22
23 Tracking down reference problems (e.g. you expect some object to be
24 destroyed, but there are still references to it that keep it alive). can
25 be very hard, although perl keeps track of all values.
26
27 The C<track> function can hlep track down some of those refernces back to
28 the variables containing them.
29
30 For example, for this fragment:
31
32 package Test;
33
34 our $var = "hi\n";
35 my $x = \$var;
36 our %hash = (ukukey => \$var);
37 our $hash2 = {ukukey2 => \$var};
38
39 sub testsub {
40 my $local = $hash2;
41 print Devel::FindRef::track \$var;
42 }
43
44 testsub;
45
46 The output is as follows (or similar to htis, in case I forget to update
47 the manpage afetr some changes):
48
49 SCALAR(0x676fa0) is
50 referenced by REF(0x676fb0), which is
51 in the lexical '$x' in CODE(0x676370), which is
52 not found anywhere I looked :(
53 referenced by REF(0x676360), which is
54 in the member 'ukukey' of HASH(0x756660), which is
55 in the global %Test::hash.
56 in the global $Test::var.
57 referenced by REF(0x6760e0), which is
58 in the member 'ukukey2' of HASH(0x676f30), which is
59 referenced by REF(0x77bcf0), which is
60 in the lexical '$local' in CODE(0x77bcb0), which is
61 in the global &Test::testsub.
62 referenced by REF(0x77bc80), which is
63 in the global $Test::hash2.
64
65
66 It is a bit convoluted to read, but basically it says that the value stored in C<$var>
67 can be found:
68
69 =over 4
70
71 =item - in some variable C<$x> whose origin is not known (I frankly have no
72 idea why, hints accepted).
73
74 =item - in the hash element with key C<ukukey> in the hash stored in C<%Test::hash>.
75
76 =item - in the global variable named C<$Test::var>.
77
78 =item - in the hash element C<ukukey2>, in the hash in the my variable
79 C<$local> in the sub C<Test::testsub> and also in the hash referenced by
80 C<$Test::hash2>.
81
82 =head1 EXPORTS
83
84 None.
85
86 =head1 FUNCTIONS
87
88 =over 4
89
90 =item $string = Devel::FindRef::track $ref[, $depth]
91
92 Track the perl value pointed to by C<$ref> up to a depth of C<$depth> and
93 return a descriptive string. C<$ref> can point at any perl value, be it
94 anonymous sub, hash, array, scalar etc.
95
96 This is the function you most often use.
97
98 =cut
99
100 sub find($);
101
102 sub track {
103 my $buf = "";
104
105 my $track; $track = sub {
106 my (undef, $depth, $indent) = @_;
107
108 if ($depth) {
109 my (@about) = find $_[0];
110 if (@about) {
111 for my $about (@about) {
112 $buf .= (" ") x $indent;
113 $buf .= $about->[0];
114 if (@$about > 1) {
115 $buf .= " $about->[1], which is\n";
116 $track->($about->[1], $depth - 1, $indent + 1);
117 } else {
118 $buf .= ".\n";
119 }
120 }
121 } else {
122 $buf .= (" ") x $indent;
123 $buf .= "not found anywhere I looked :(\n";
124 }
125 } else {
126 $buf .= (" ") x $indent;
127 $buf .= "not referenced within the search depth.\n";
128 }
129 };
130
131 $buf .= "$_[0] is\n";
132 $track->($_[0], $_[1] || 10, 1);
133 $buf
134 }
135
136 =item @references = Devel::FindRef::find $ref
137
138 Return arrayrefs that contain [$message, $ref] pairs. The message
139 describes what kind of reference was found and the C<$ref> is the
140 reference itself, which cna be omitted if C<find> decided to end the
141 search.
142
143 The C<track> function uses this to find references to the value you are
144 interested in and recurses on the returned references.
145
146 =cut
147
148 sub find($) {
149 my ($about, $excl) = &find_;
150 my %excl = map +($_ => 1), @$excl;
151 grep !$excl{$_->[1] + 0}, @$about
152 }
153
154 =item $ref = Devel::FindRef::ref2ptr $ptr
155
156 Sometimes you know (from debugging output) the address of a perl scalar
157 you are interested in. This function can be used to turn the address into
158 a reference to that scalar. It is quite safe to call on valid addresses,
159 but extremely dangerous to call on invalid ones.
160
161 =back
162
163 =head1 AUTHOR
164
165 Marc Lehmann <pcg@goof.com>.
166
167 =head1 BUGS
168
169 Only code values, arrays, hashes and scalars are being looked at. Tied
170 values and magic is not currently being investigated.
171
172 =head1 COPYRIGHT AND LICENSE
173
174 Copyright (C) 2007 by Marc Lehmann.
175
176 This library is free software; you can redistribute it and/or modify
177 it under the same terms as Perl itself, either Perl version 5.8.8 or,
178 at your option, any later version of Perl 5 you may have available.
179
180 =cut
181
182 1
183