Subject: | Support closures closing over weak references |
Currently, when asked to look for cycles (excluding weak ones) in
closures, that close over weak references, cycles are reported, although
no non-weak cycles exist.
The attached patch adds tests to demonstrate the issue and changes
Cycle.pm to make the tests pass.
Subject: | 0001-Support-closures-closing-over-weak-references.patch |
From 7d90c426d2e872b7ff10b0cfb713d48f1efba39d Mon Sep 17 00:00:00 2001
From: Florian Ragwitz <rafl@debian.org>
Date: Sat, 27 Jun 2009 13:38:20 +0200
Subject: [PATCH] Support closures closing over weak references.
---
lib/Devel/Cycle.pm | 4 +++-
t/Devel-Cycle.t | 12 ++++++++++--
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/lib/Devel/Cycle.pm b/lib/Devel/Cycle.pm
index 91d11ee..0d182f6 100644
--- a/lib/Devel/Cycle.pm
+++ b/lib/Devel/Cycle.pm
@@ -174,8 +174,10 @@ sub _find_cycle_CODE {
my $closed_vars = PadWalker::closed_over( $current );
foreach my $varname ( sort keys %$closed_vars ) {
my $value = $closed_vars->{$varname};
+ my $isweak = ref $value eq 'REF' && isweak(${ $value });
+ next if !$inc_weak_refs && $isweak;
_find_cycle_dispatch($value,{%$seenit},$callback,$inc_weak_refs,$complain,
- (@report,['CODE',$varname,$current => $value]));
+ (@report,['CODE',$varname,$current => $value,$inc_weak_refs?$isweak:()]));
}
}
diff --git a/t/Devel-Cycle.t b/t/Devel-Cycle.t
index 608c8af..a27d979 100644
--- a/t/Devel-Cycle.t
+++ b/t/Devel-Cycle.t
@@ -5,7 +5,7 @@
# change 'tests => 1' to 'tests => last_test_to_print';
-use Test::More tests => 12;
+use Test::More tests => 13;
use Scalar::Util qw(weaken isweak);
BEGIN { use_ok('Devel::Cycle') };
@@ -80,10 +80,18 @@ SKIP:
my @cyclical = [];
$cyclical[0] = \@cyclical;
- my $sub = sub { return \@cyclical, \%cyclical; };
+ my $foo = \@cyclical;
+ weaken($foo);
+
+ my $sub = sub { return \@cyclical, \%cyclical, $foo; };
find_cycle($sub,sub {$counter++});
is($counter,3,'found three cycles in $cyclical closure');
+
+ $counter = 0;
+ find_weakened_cycle($sub);
+ find_weakened_cycle($sub,sub {$counter++});
+ is($counter,4,'found three cycles (including weakened ones) in closure');
}
{
--
1.6.3.1.57.gbd5ef