Allow packages to be cleaned multiple times mirror/master
Graham Knop [Fri, 24 Oct 2014 19:29:06 +0000 (15:29 -0400)]
Originally the functionality was implmented via Filter::Util::Call, but when
it was removed in [1] the "one per scope" logic remained. Given the reliance
on B::Hooks::EndOfScope none of this is longer required.

[1] https://metacpan.org/diff/file?target=PHAYLON%2Fnamespace-clean-0.07%2Flib%2Fnamespace%2Fclean.pm&source=PHAYLON%2Fnamespace-clean-0.06%2Flib%2Fnamespace%2Fclean.pm

Changes
lib/namespace/clean.pm
t/10-pure-perl.t
t/11-multiclean-in-scope.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index 0ed9350..2379d72 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,4 +1,5 @@
 
+        - Allow packages to be cleaned multiple times
         - Ensure the debugger workarounds are applied only when
           DB::sub is actively used (they are superfluous otherwise)
         - Work around P5#72210, resulting in fails on 5.8.8 -Duselongdouble
index 80d017a..19f4519 100644 (file)
@@ -180,13 +180,9 @@ sub import {
             $store->{remove}{ $f } = 1;
         }
 
-        # register EOF handler on first call to import
-        unless ($store->{handler_is_installed}) {
-            on_scope_end {
-                $RemoveSubs->($cleanee, $store, keys %{ $store->{remove} });
-            };
-            $store->{handler_is_installed} = 1;
-        }
+        on_scope_end {
+            $RemoveSubs->($cleanee, $store, keys %{ $store->{remove} });
+        };
 
         return 1;
     }
index 744688e..01ae92e 100644 (file)
@@ -17,7 +17,7 @@ BEGIN {
 
   $ENV{B_HOOKS_ENDOFSCOPE_IMPLEMENTATION} = 'PP';
   $ENV{PACKAGE_STASH_IMPLEMENTATION} = 'PP';
-  plan tests => 14;
+  plan tests => 15;
 }
 
 use B::Hooks::EndOfScope 0.12;
diff --git a/t/11-multiclean-in-scope.t b/t/11-multiclean-in-scope.t
new file mode 100644 (file)
index 0000000..a84bc7d
--- /dev/null
@@ -0,0 +1,78 @@
+use strict;
+use warnings;
+
+use Test::More tests => 13;
+
+eval q{
+  package Class1;
+  sub cleaned1 {}
+  use namespace::clean;
+  1;
+} or die $@;
+
+ok !Class1->can('cleaned1'), 'basic clean';
+
+eval q{
+  package Class1;
+  sub cleaned2 {}
+  use namespace::clean;
+  1;
+} or die $@;
+
+ok !Class1->can('cleaned2'), 'clean same class again';
+
+eval q{
+  package Class2;
+  sub cleaned1 {}
+  use namespace::clean;
+  sub left1 {}
+  no namespace::clean;
+  sub cleaned2 {}
+  use namespace::clean;
+  1;
+} or die $@;
+
+ok !Class2->can('cleaned1'), 'basic clean before no';
+ok +Class2->can('left1'),    'basic no clean';
+ok !Class2->can('cleaned2'), 'basic clean after no';
+
+eval q{
+  package Class2;
+  sub cleaned3 {}
+  use namespace::clean;
+  sub left2 {}
+  no namespace::clean;
+  sub cleaned4 {}
+  use namespace::clean;
+  1;
+} or die $@;
+
+ok !Class2->can('cleaned3'),  'clean again before no';
+ok +Class2->can('left2'),     'clean again no clean';
+ok !Class2->can('cleaned4'),  'clean again after no';
+
+eval q{
+  package Class3;
+  sub cleaned1 {}
+  use namespace::clean;
+  sub cleaned2 {}
+  no namespace::clean;
+  {
+    sub cleaned3 {}
+    use namespace::clean;
+  }
+  BEGIN {
+    package main;
+    ok !Class3->can('cleaned3'), 'clean inner scope';
+    {
+      local $TODO = 'unable to differentiate scopes';
+      ok +Class3->can('cleaned1'), 'clean inner scope leaves outer';
+    }
+    ok +Class3->can('cleaned2'), 'clean inner scope leaves outer no';
+  }
+  use namespace::clean;
+  1;
+} or die $@;
+
+ok !Class3->can('cleaned1'), 'clean after scoped';
+ok +Class3->can('cleaned2'), 'no clean after scoped';