From: Florian Ragwitz Date: Sun, 18 Feb 2007 23:00:00 +0000 (+0100) Subject: Import namespace-clean-0.02.tar.gz. X-Git-Tag: 0.02^0 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9b680ffe76a7293ec454dbc07947cd7697520428;p=p5sagit%2Fnamespace-clean.git Import namespace-clean-0.02.tar.gz. --- diff --git a/Changes b/Changes index 46c9251..48090f0 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,7 @@ + [0.02] Tue Feb 20 00:38:24 CET 2007 + - Added unimport behaviour + [0.01] Sun Feb 18 17:33:18 CET 2007 - Initial Version diff --git a/MANIFEST b/MANIFEST index 6ef7d07..1daf5f9 100644 --- a/MANIFEST +++ b/MANIFEST @@ -15,8 +15,10 @@ README t/00-basic.t t/01-function-wipeout.t t/02-inheritance.t +t/03-unimport.t t/10-pod.t t/11-pod-coverage.t t/lib/ExporterTest.pm t/lib/FunctionWipeout.pm t/lib/Inheritance.pm +t/lib/Unimport.pm diff --git a/META.yml b/META.yml index 2102240..aaea6eb 100644 --- a/META.yml +++ b/META.yml @@ -14,4 +14,4 @@ no_index: requires: Filter::EOF: 0.02 Symbol: 0 -version: 0.01 +version: 0.02 diff --git a/README b/README index c9a67b9..c7f0827 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ NAME namespace::clean - Keep imports out of your namespace VERSION - 0.01 + 0.02 SYNOPSIS package Foo; @@ -17,13 +17,21 @@ SYNOPSIS sub baz { bar() } # still defined, 'bar' still bound + no namespace::clean; + + sub quux { baz() } # will be removed again + + use namespace::clean; + ### Will print: # No # No # Yes + # No print +(__PACKAGE__->can('croak') ? 'Yes' : 'No'), "\n"; print +(__PACKAGE__->can('bar') ? 'Yes' : 'No'), "\n"; print +(__PACKAGE__->can('baz') ? 'Yes' : 'No'), "\n"; + print +(__PACKAGE__->can('quux') ? 'Yes' : 'No'), "\n"; 1; @@ -48,6 +56,17 @@ METHODS Filter::EOF cleanup routine to remove those symbols from the package at the end of the compile-time. + unimport + This method will be called when you do a + + no namespace::clean; + + It will start a new section of code that defines functions to clean up. + + get_class_store + This returns a reference to a hash in your package containing + information about function names included and excluded from removal. + get_functions Takes a class as argument and returns all currently defined functions in it as a hash reference with the function name as key and a typeglob diff --git a/lib/namespace/clean.pm b/lib/namespace/clean.pm index 206148c..434e2da 100644 --- a/lib/namespace/clean.pm +++ b/lib/namespace/clean.pm @@ -9,17 +9,18 @@ namespace::clean - Keep imports out of your namespace use warnings; use strict; -use vars qw( $VERSION ); +use vars qw( $VERSION $STORAGE_VAR ); use Symbol qw( qualify_to_ref ); use Filter::EOF; =head1 VERSION -0.01 +0.02 =cut -$VERSION = 0.01; +$VERSION = 0.02; +$STORAGE_VAR = '__NAMESPACE_CLEAN_STORAGE'; =head1 SYNOPSIS @@ -35,13 +36,21 @@ $VERSION = 0.01; sub baz { bar() } # still defined, 'bar' still bound + no namespace::clean; + + sub quux { baz() } # will be removed again + + use namespace::clean; + ### Will print: # No # No # Yes + # No print +(__PACKAGE__->can('croak') ? 'Yes' : 'No'), "\n"; print +(__PACKAGE__->can('bar') ? 'Yes' : 'No'), "\n"; print +(__PACKAGE__->can('baz') ? 'Yes' : 'No'), "\n"; + print +(__PACKAGE__->can('quux') ? 'Yes' : 'No'), "\n"; 1; @@ -76,16 +85,65 @@ sub import { my $cleanee = caller; my $functions = $pragma->get_functions($cleanee); + my $store = $pragma->get_class_store($cleanee); - Filter::EOF->on_eof_call(sub { - for my $f (keys %$functions) { - next unless $functions->{ $f } - and *{ $functions->{ $f } }{CODE}; - { no strict 'refs'; + for my $f (keys %$functions) { + next unless $functions->{ $f } + and *{ $functions->{ $f } }{CODE}; + $store->{remove}{ $f } = 1; + } + + unless ($store->{handler_is_installed}) { + Filter::EOF->on_eof_call(sub { + for my $f (keys %{ $store->{remove} }) { + next if $store->{exclude}{ $f }; + no strict 'refs'; delete ${ "${cleanee}::" }{ $f }; } - } - }); + }); + $store->{handler_is_installed} = 1; + } + + return 1; +} + +=head2 unimport + +This method will be called when you do a + + no namespace::clean; + +It will start a new section of code that defines functions to clean up. + +=cut + +sub unimport { + my ($pragma) = @_; + + my $cleanee = caller; + my $functions = $pragma->get_functions($cleanee); + my $store = $pragma->get_class_store($cleanee); + + for my $f (keys %$functions) { + next if $store->{remove}{ $f } + or $store->{exclude}{ $f }; + $store->{exclude}{ $f } = 1; + } + + return 1; +} + +=head2 get_class_store + +This returns a reference to a hash in your package containing information +about function names included and excluded from removal. + +=cut + +sub get_class_store { + my ($pragma, $class) = @_; + no strict 'refs'; + return \%{ "${class}::${STORAGE_VAR}" }; } =head2 get_functions diff --git a/t/03-unimport.t b/t/03-unimport.t new file mode 100644 index 0000000..126bc10 --- /dev/null +++ b/t/03-unimport.t @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +use warnings; +use strict; + +use FindBin; +use lib "$FindBin::Bin/lib"; +use Test::More tests => 6; + +use_ok('Unimport'); + +ok( !Unimport->can('foo'), + 'first function correctly removed' ); +ok( Unimport->can('bar'), + 'excluded method still in package' ); +ok( !Unimport->can('baz'), + 'second function correctly removed' ); +ok( Unimport->can('qux'), + 'last method still in package' ); +is( Unimport->qux, 23, + 'all functions are still bound' ); + diff --git a/t/lib/Unimport.pm b/t/lib/Unimport.pm new file mode 100644 index 0000000..82f05a8 --- /dev/null +++ b/t/lib/Unimport.pm @@ -0,0 +1,19 @@ +package Unimport; +use warnings; +use strict; + +sub foo { 23 } + +use namespace::clean; + +sub bar { foo() } + +no namespace::clean; + +sub baz { bar() } + +use namespace::clean; + +sub qux { baz() } + +1;