Subject: | [PATCH] Doesn't find all code refs |
I found 3 cases where it doesn't find all code refs.
1. Variables referenced in closures (anonymous code refs)
2. Last variable used in a code ref
3. Code refs that are parents of inner code refs.
Test cases for each:
Case 1:
use Devel::FindRef;
my $var = "hi\n";
my $t = sub {$var . "bye\n"};
print Devel::FindRef::track(\$var);
Case 2:
use Devel::FindRef;
my $var = "hi\n";
my $t = sub {$var};
print Devel::FindRef::track(\$var);
Case 3:
use Devel::FindRef;
sub testsub {
my $var = "hi\n";
my $t = sub {
sub test_inner { "foo" }
$var;
};
$t->();
print Devel::FindRef::track(\$var);
}
testsub;
Some points to note:
* The attached patch fixes all these problems, but could do with more
refinement.
* You will probably have to modify the POD documentation to remove
the "not found anywhere I looked :(" from the example output because
now it does find the code refs.
* This patch exposes some circular references in Perl's internals.
Perhaps looking at the WEAKOUTSIDE CV-flag would help, but for my
purposes I preferred to err on the side of too much output than to
risk missing a valid reference.
I hope this helps.
Subject: | Devel-FindRef.patch |
diff -ur Devel-FindRef-1.1/FindRef.xs Devel-FindRef-1.1-mod/FindRef.xs
--- Devel-FindRef-1.1/FindRef.xs 2007-12-29 15:53:16.000000000 -0500
+++ Devel-FindRef-1.1-mod/FindRef.xs 2008-04-23 22:29:18.000000000 -0400
@@ -118,6 +118,7 @@
case SVt_PVCV:
{
int depth = CvDEPTH (sv);
+ if (depth == 0 && CvPADLIST(sv)) depth = 1;
if (depth)
{
@@ -129,13 +130,15 @@
av_push (excl, newSVuv (PTR2UV (pad))); /* exclude pads themselves from being found */
- for (i = AvFILLp (pad); i--; )
+ for (i = AvFILLp (pad)+1; i--; )
if (AvARRAY (pad)[i] == targ)
res_pair (form ("in the lexical '%s' in", SvPVX (AvARRAY (AvARRAY (padlist)[0])[i])));
--depth;
}
}
+ if ((SV*)CvOUTSIDE(sv) == targ)
+ res_pair ("the containing scope for");
}
break;