compile each thing in a separate package, to avoid leakage
Jesse Luehrs [Tue, 2 Aug 2011 06:10:22 +0000 (01:10 -0500)]
lib/Eval/Closure.pm
t/compiling-package.t

index 23cf250..42c20da 100644 (file)
@@ -207,14 +207,18 @@ sub _clean_eval_closure {
     }
 }
 
+$Eval::Closure::SANDBOX_ID = 0;
+
 sub _clean_eval {
-    package # hide from PAUSE
-        Eval::Closure::Sandbox;
-    local $@;
-    local $SIG{__DIE__};
-    my $compiler = eval $_[0];
-    my $e = $@;
-    return [ $compiler, $e ];
+    $Eval::Closure::SANDBOX_ID++;
+    return eval <<EVAL;
+package Eval::Closure::Sandbox_$Eval::Closure::SANDBOX_ID;
+local \$@;
+local \$SIG{__DIE__};
+my \$compiler = eval \$_[0];
+my \$e = \$@;
+[ \$compiler, \$e ];
+EVAL
 }
 
 sub _make_compiler_source {
index 5c3764f..09b4d0b 100644 (file)
@@ -5,13 +5,30 @@ use Test::More;
 
 use Eval::Closure;
 
-my $code = eval_closure(
-    source => 'no strict "refs"; sub { keys %{__PACKAGE__ . "::"} }',
-);
+{
+    my $code = eval_closure(
+        source => 'no strict "refs"; sub { keys %{__PACKAGE__ . "::"} }',
+    );
 
-# defining the sub { } creates __ANON__, calling 'no strict' creates BEGIN
-my @stash_keys = grep { $_ ne '__ANON__' && $_ ne 'BEGIN' } $code->();
+    # defining the sub { } creates __ANON__, calling 'no strict' creates BEGIN
+    my @stash_keys = grep { $_ ne '__ANON__' && $_ ne 'BEGIN' } $code->();
 
-is_deeply([@stash_keys], [], "compiled in an empty package");
+    is_deeply([@stash_keys], [], "compiled in an empty package");
+}
+
+{
+    # the more common case where you'd run into this is imported subs
+    # for instance, Bread::Board::as vs Moose::Util::TypeConstraints::as
+    my $c1 = eval_closure(
+        source => 'no strict "vars"; sub { ++$foo }',
+    );
+    my $c2 = eval_closure(
+        source => 'no strict "vars"; sub { --$foo }',
+    );
+    is($c1->(), 1);
+    is($c1->(), 2);
+    is($c2->(), -1);
+    is($c2->(), -2);
+}
 
 done_testing;