avoid duplicates in @INC, they cause leaks in mod_perl etc
Gurusamy Sarathy [Sun, 10 Oct 1999 02:23:52 +0000 (02:23 +0000)]
(suggested by Tod Irwin <irwin@stockmaster.com>)

p4raw-id: //depot/perl@4327

lib/lib.pm

index 6e6e15e..ea3ea5e 100644 (file)
@@ -10,13 +10,12 @@ my $archname = $Config{'archname'};
 
 sub import {
     shift;
+
+    my %names;
     foreach (reverse @_) {
-       ## Ignore this if not defined.
-       next unless defined($_);
        if ($_ eq '') {
            require Carp;
            Carp::carp("Empty compile time value given to use lib");
-                                                       # at foo.pl line ...
        }
        if (-e && ! -d _) {
            require Carp;
@@ -29,27 +28,23 @@ sub import {
            unshift(@INC, "$_/$archname")    if -d "$_/$archname/auto";
            unshift(@INC, "$_/$archname/$]") if -d "$_/$archname/$]/auto";
        }
+       # remove trailing duplicates
+       @INC = grep { ++$names{$_} == 1 } @INC;
     }
 }
 
 
 sub unimport {
     shift;
-    my $mode = shift if $_[0] =~ m/^:[A-Z]+/;
 
     my %names;
-    foreach(@_) {
+    foreach (@_) {
        ++$names{$_};
        ++$names{"$_/$archname"} if -d "$_/$archname/auto";
     }
 
-    if ($mode and $mode eq ':ALL') {
-       # Remove ALL instances of each named directory.
-       @INC = grep { !exists $names{$_} } @INC;
-    } else {
-       # Remove INITIAL instance(s) of each named directory.
-       @INC = grep { --$names{$_} < 0   } @INC;
-    }
+    # Remove ALL instances of each named directory.
+    @INC = grep { !exists $names{$_} } @INC;
 }
 
 1;
@@ -74,7 +69,7 @@ It is typically used to add extra directories to perl's search path so
 that later C<use> or C<require> statements will find modules which are
 not located on perl's default search path.
 
-=head2 ADDING DIRECTORIES TO @INC
+=head2 Adding directories to @INC
 
 The parameters to C<use lib> are added to the start of the perl search
 path. Saying
@@ -90,10 +85,10 @@ checks to see if a directory called $dir/$archname/auto exists.
 If so the $dir/$archname directory is assumed to be a corresponding
 architecture specific directory and is added to @INC in front of $dir.
 
-If LIST includes both $dir and $dir/$archname then $dir/$archname will
-be added to @INC twice (if $dir/$archname/auto exists).
+To avoid memory leaks, all trailing duplicate entries in @INC are
+removed.
 
-=head2 DELETING DIRECTORIES FROM @INC
+=head2 Deleting directories from @INC
 
 You should normally only add directories to @INC.  If you need to
 delete directories from @INC take care to only delete those which you
@@ -101,24 +96,15 @@ added yourself or which you are certain are not needed by other modules
 in your script.  Other modules may have added directories which they
 need for correct operation.
 
-By default the C<no lib> statement deletes the I<first> instance of
-each named directory from @INC.  To delete multiple instances of the
-same name from @INC you can specify the name multiple times.
-
-To delete I<all> instances of I<all> the specified names from @INC you can
-specify ':ALL' as the first parameter of C<no lib>. For example:
-
-    no lib qw(:ALL .);
+The C<no lib> statement deletes all instances of each named directory
+from @INC.
 
 For each directory in LIST (called $dir here) the lib module also
 checks to see if a directory called $dir/$archname/auto exists.
 If so the $dir/$archname directory is assumed to be a corresponding
 architecture specific directory and is also deleted from @INC.
 
-If LIST includes both $dir and $dir/$archname then $dir/$archname will
-be deleted from @INC twice (if $dir/$archname/auto exists).
-
-=head2 RESTORING ORIGINAL @INC
+=head2 Restoring original @INC
 
 When the lib module is first loaded it records the current value of @INC
 in an array C<@lib::ORIG_INC>. To restore @INC to that value you
@@ -136,4 +122,3 @@ FindBin - optional module which deals with paths relative to the source file.
 Tim Bunce, 2nd June 1995.
 
 =cut
-