make the namespace cache lazy and weak, in case the stash is deleted
[gitmo/Package-Stash.git] / lib / Package / Stash / PP.pm
index 446642b..653eeaf 100644 (file)
@@ -4,7 +4,7 @@ use warnings;
 # ABSTRACT: pure perl implementation of the Package::Stash API
 
 use Carp qw(confess);
-use Scalar::Util qw(blessed reftype);
+use Scalar::Util qw(blessed reftype weaken);
 use Symbol;
 # before 5.12, assigning to the ISA glob would make it lose its magical ->isa
 # powers
@@ -24,15 +24,8 @@ sub new {
     my $class = shift;
     my ($package) = @_;
     my $namespace;
-    {
-        no strict 'refs';
-        # supposedly this caused a bug in earlier perls, but I can't reproduce
-        # it, so re-enabling the caching
-        $namespace = \%{$package . '::'};
-    }
     return bless {
-        'package'   => $package,
-        'namespace' => $namespace,
+        'package' => $package,
     }, $class;
 }
 
@@ -45,6 +38,17 @@ sub name {
 sub namespace {
     confess "Can't call namespace as a class method"
         unless blessed($_[0]);
+    return $_[0]->{namespace} if defined $_[0]->{namespace};
+
+    {
+        no strict 'refs';
+        # supposedly this caused a bug in earlier perls, but I can't reproduce
+        # it, so re-enabling the caching
+        $_[0]->{namespace} = \%{$_[0]->name . '::'};
+    }
+
+    weaken($_[0]->{namespace});
+
     return $_[0]->{namespace};
 }
 
@@ -196,13 +200,7 @@ sub get_symbol {
             }
         }
         else {
-            if ($type eq 'CODE') {
-                # this effectively "de-vivifies" the code slot. if we don't do
-                # this, referencing the coderef at the end of this function
-                # will cause perl to auto-vivify a stub coderef in the slot,
-                # which isn't what we want
-                $self->add_symbol($variable);
-            }
+            return undef;
         }
     }
 
@@ -351,6 +349,12 @@ considered a feature in some cases (this is how L<namespace::clean> works, for
 instance), but should not be relied upon - use C<remove_glob> directly if you
 want this behavior.
 
+=item * Some minor memory leaks
+
+The pure perl implementation has a couple minor memory leaks (see the TODO
+tests in t/20-leaks.t) that I'm having a hard time tracking down - these may be
+core perl bugs, it's hard to tell.
+
 =back
 
 Please report any bugs through RT: email
@@ -402,6 +406,22 @@ Jesse Luehrs <doy at tozt dot net>
 Mostly copied from code from L<Class::MOP::Package>, by Stevan Little and the
 Moose Cabal.
 
+=begin Pod::Coverage
+
+BROKEN_ISA_ASSIGNMENT
+add_symbol
+get_all_symbols
+get_or_add_symbol
+get_symbol
+has_symbol
+list_all_symbols
+name
+namespace
+new
+remove_glob
+
+=end Pod::Coverage
+
 =cut
 
 1;