ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Devel-FindRef/FindRef.pm
(Generate patch)

Comparing Devel-FindRef/FindRef.pm (file contents):
Revision 1.18 by root, Mon Dec 1 13:22:43 2008 UTC vs.
Revision 1.27 by root, Thu Apr 5 05:11:14 2012 UTC

1package Devel::FindRef; 1package Devel::FindRef;
2 2
3no warnings; # I hate warning nazis 3use common::sense;
4use strict;
5 4
6use XSLoader; 5use XSLoader;
7use Scalar::Util; 6use Scalar::Util;
8 7
9BEGIN { 8BEGIN {
10 our $VERSION = '1.31'; 9 our $VERSION = '1.422';
11 XSLoader::load __PACKAGE__, $VERSION; 10 XSLoader::load __PACKAGE__, $VERSION;
12} 11}
13 12
14=head1 NAME 13=head1 NAME
15 14
32the variables containing them. 31the variables containing them.
33 32
34For example, for this fragment: 33For example, for this fragment:
35 34
36 package Test; 35 package Test;
36
37 use Devel::FindRef;
38 use Scalar::Util;
37 39
38 our $var = "hi\n"; 40 our $var = "hi\n";
39 my $x = \$var; 41 my $global_my = \$var;
40 our %hash = (ukukey => \$var); 42 our %global_hash = (ukukey => \$var);
41 our $hash2 = {ukukey2 => \$var}; 43 our $global_hashref = { ukukey2 => \$var };
42 44
43 sub testsub { 45 sub testsub {
44 my $local = $hash2; 46 my $testsub_local = $global_hashref;
45 print Devel::FindRef::track \$var; 47 print Devel::FindRef::track \$var;
46 } 48 }
47 49
48 testsub; 50
51 my $closure = sub {
52 my $closure_var = \$_[0];
53 Scalar::Util::weaken (my $weak_ref = \$var);
54 testsub;
55 };
56
57 $closure->($var);
49 58
50The output is as follows (or similar to this, in case I forget to update 59The output is as follows (or similar to this, in case I forget to update
51the manpage after some changes): 60the manpage after some changes):
52 61
53 SCALAR(0x814ece8) is 62 SCALAR(0x7cc888) [refcount 6] is
63 +- referenced by REF(0x8abcc8) [refcount 1], which is
64 | the lexical '$closure_var' in CODE(0x8abc50) [refcount 4], which is
65 | +- the closure created at tst:18.
66 | +- referenced by REF(0x7d3c58) [refcount 1], which is
67 | | the lexical '$closure' in CODE(0x7ae530) [refcount 2], which is
68 | | +- the containing scope for CODE(0x8ab430) [refcount 3], which is
69 | | | the global &Test::testsub.
70 | | +- the main body of the program.
71 | +- the lexical '&' in CODE(0x7ae530) [refcount 2], which was seen before.
72 +- referenced by REF(0x7cc7c8) [refcount 1], which is
73 | the lexical '$global_my' in CODE(0x7ae530) [refcount 2], which was seen before.
54 +- in the global $Test::var. 74 +- the global $Test::var.
55 +- referenced by REF(0x814f9e4), which is 75 +- referenced by REF(0x7cc558) [refcount 1], which is
56 | in the lexical '$x' in CODE(0x814ed78), which is 76 | the member 'ukukey2' of HASH(0x7ae140) [refcount 2], which is
57 | the containing scope for CODE(0x820c4b0), which is 77 | +- referenced by REF(0x8abad0) [refcount 1], which is
58 | in the global &Test::testsub. 78 | | the lexical '$testsub_local' in CODE(0x8ab430) [refcount 3], which was seen before.
79 | +- referenced by REF(0x8ab4f0) [refcount 1], which is
80 | the global $Test::global_hashref.
59 +- referenced by REF(0x814ed6c), which is 81 +- referenced by REF(0x7ae518) [refcount 1], which is
60 | in the member 'ukukey' of HASH(0x81da20c), which is 82 | the member 'ukukey' of HASH(0x7d3bb0) [refcount 1], which is
61 | in the global %Test::hash. 83 | the global %Test::global_hash.
62 +- referenced by REF(0x814ec28), which is 84 +- referenced by REF(0x7ae2f0) [refcount 1], which is
63 | not found anywhere I looked :( 85 a temporary on the stack.
64 +- referenced by REF(0x814eb44), which is
65 in the member 'ukukey2' of HASH(0x814f99c), which is
66 +- referenced by REF(0x820c450), which is
67 | in the lexical '$local' in CODE(0x820c4b0), which was seen before.
68 +- referenced by REF(0x820c204), which is
69 in the global $Test::hash2.
70 86
71It is a bit convoluted to read, but basically it says that the value 87It is a bit convoluted to read, but basically it says that the value
72stored in C<$var> can be found: 88stored in C<$var> is referenced by:
73 89
74=over 4 90=over 4
75 91
76=item - in some variable C<$x> whose origin is not known (I frankly have no 92=item - the lexical C<$closure_var> (0x8abcc8), which is inside an instantiated
77idea why, hints accepted). 93closure, which in turn is used quite a bit.
78 94
79=item - in the hash element with key C<ukukey> in the hash stored in C<%Test::hash>. 95=item - the package-level lexical C<$global_my>.
80 96
81=item - in the global variable named C<$Test::var>. 97=item - the global package variable named C<$Test::var>.
82 98
83=item - in the hash element C<ukukey2>, in the hash in the my variable 99=item - the hash element C<ukukey2>, in the hash in the my variable
84C<$local> in the sub C<Test::testsub> and also in the hash referenced by 100C<$testsub_local> in the sub C<Test::testsub> and also in the hash
101C<$referenced by Test::hash2>.
102
103=item - the hash element with key C<ukukey> in the hash stored in
85C<$Test::hash2>. 104C<%Test::hash>.
105
106=item - some anonymous mortalised reference on the stack (which is caused
107by calling C<track> with the expression C<\$var>, which creates the
108reference).
86 109
87=back 110=back
111
112And all these account for six reference counts.
113
88 114
89=head1 EXPORTS 115=head1 EXPORTS
90 116
91None. 117None.
92 118
124 150
125 if ($depth) { 151 if ($depth) {
126 my (@about) = find $$refref; 152 my (@about) = find $$refref;
127 if (@about) { 153 if (@about) {
128 for my $about (@about) { 154 for my $about (@about) {
155 $about->[0] =~ s/([^\x20-\x7e])/sprintf "\\{%02x}", ord $1/ge;
129 $buf .= "$indent" . (@about > 1 ? "+- " : " ") . $about->[0]; 156 $buf .= "$indent" . (@about > 1 ? "+- " : "") . $about->[0];
130 if (@$about > 1) { 157 if (@$about > 1) {
131 if ($seen{ref2ptr $about->[1]}++) { 158 if ($seen{ref2ptr $about->[1]}++) {
132 $buf .= " " . (_f $about->[1]) . ", which was seen before.\n"; 159 $buf .= " " . (_f $about->[1]) . ", which was seen before.\n";
133 } else { 160 } else {
134 $buf .= " " . (_f $about->[1]) . ", which is\n"; 161 $buf .= " " . (_f $about->[1]) . ", which is\n";
145 $buf .= "$indent not referenced within the search depth.\n"; 172 $buf .= "$indent not referenced within the search depth.\n";
146 } 173 }
147 }; 174 };
148 175
149 $buf .= (_f $ref) . " is\n"; 176 $buf .= (_f $ref) . " is\n";
177
150 $track->(\$ref, $depth || $ENV{PERL_DEVEL_FINDREF_DEPTH} || 10, ""); 178 $track->(\$ref, $depth || $ENV{PERL_DEVEL_FINDREF_DEPTH} || 10, "");
151 $buf 179 $buf
152} 180}
153 181
154=item @references = Devel::FindRef::find $ref 182=item @references = Devel::FindRef::find $ref
164=cut 192=cut
165 193
166sub find($) { 194sub find($) {
167 my ($about, $excl) = &find_; 195 my ($about, $excl) = &find_;
168 my %excl = map +($_ => undef), @$excl; 196 my %excl = map +($_ => undef), @$excl;
169 grep !exists $excl{ref2ptr $_->[1]}, @$about 197 grep !($#$_ && exists $excl{ref2ptr $_->[1]}), @$about
170} 198}
171 199
172=item $ref = Devel::FindRef::ptr2ref $integer 200=item $ref = Devel::FindRef::ptr2ref $integer
173 201
174Sometimes you know (from debugging output) the address of a perl scalar 202Sometimes you know (from debugging output) the address of a perl scalar
177call on valid addresses, but extremely dangerous to call on invalid ones. 205call on valid addresses, but extremely dangerous to call on invalid ones.
178 206
179 # we know that HASH(0x176ff70) exists, so turn it into a hashref: 207 # we know that HASH(0x176ff70) exists, so turn it into a hashref:
180 my $ref_to_hash = Devel::FindRef::ptr2ref 0x176ff70; 208 my $ref_to_hash = Devel::FindRef::ptr2ref 0x176ff70;
181 209
182=item $ref = Devel::FindRef::ref2ptr $reference 210=item $ptr = Devel::FindRef::ref2ptr $reference
183 211
184The opposite of C<ptr2ref>, above: returns the internal address of the 212The opposite of C<ptr2ref>, above: returns the internal address of the
185value pointed to by the passed reference. I<No checks whatsoever will be 213value pointed to by the passed reference. I<No checks whatsoever will be
186done>, so don't use this. 214done>, so don't use this.
187 215

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines