Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I completely delete a package in Perl?

How do you completely delete a package in Perl? This means not only the package variables, but also any magic tables that Perl updates to handle inheritance changes and other things.

This simple test:

use warnings; use strict;
use Test::LeakTrace;
use Symbol 'delete_package';

leaktrace {
   package test;
   our $x = 1;

   package main;
   delete_package 'test';
};

results in the following output:

leaked ARRAY(0x81c930)  from /lib/perl5/5.10.1/Symbol.pm line 166.
leaked HASH(0x827760)   from /lib/perl5/5.10.1/Symbol.pm line 166.
leaked SCALAR(0x821920) from /lib/perl5/5.10.1/Symbol.pm line 166.

Using the -verbose flag for leaktrace results in screenfuls of data which I can post on request.

Things get worse if the line our @ISA = 'main'; is added to the test package:

leaked ARRAY(0x81cd10) from so.pl line 32.
leaked SCALAR(0x81c930) from so.pl line 32.
leaked ARRAY(0x8219d0) from so.pl line 32.
leaked HASH(0x8219c0) from so.pl line 32.
leaked SCALAR(0x8219b0) from so.pl line 32.
leaked HASH(0x8219a0) from so.pl line 32.
leaked SCALAR(0x821970) from /lib/perl5/5.10.1/Symbol.pm line 161.
leaked HASH(0x821950) from so.pl line 32.
leaked SCALAR(0x821940) from so.pl line 32.

Line 32 is where the our @ISA is.

To illustrate that these are indeed leaks and not just noise from the interpreter:

my $num = 0;
while (1) {
    no strict 'refs';
    @{$num.'::ISA'} = 'main';
    delete_package $num++;
}

will eat memory at a constant rate

So, is there a better way to get rid of a package than Symbol's delete_package? Is there something else that I have to do to help it along?

I have seen the same behavior in 5.8.8, 5.10.1, and 5.12

like image 880
Eric Strom Avatar asked Sep 27 '10 19:09

Eric Strom


People also ask

How do I uninstall a Perl module?

Type cpanm --uninstall Module::Name (note the " m ") to uninstall the module with cpanminus.

How do I close CPAN?

You can use exit or quit to exit cpan . It will also exit when its STDIN reaches EOF (which can be done using Ctrl-D on unix). You talk of Ctrl-Z, which stops (suspends) it, but doesn't exit it. Use fg to return to cpan after stopping it.

What is package in Perl script?

A Perl package is a collection of code which resides in its own namespace. Perl module is a package defined in a file having the same name as that of the package and having extension . pm. Two different modules may contain a variable or a function of the same name.

Where do Perl modules get installed?

Note: If pmall is not in your PATH, it is located in the \bin directory in the root directory of your Perl installation. You can use the which perl command to find the location of the Perl interpreter in a Perl installation that is supplied by your operating system.


1 Answers

So this is a bug in perl, a reported one even as you discovered. Short of fixing that, it seems like your only way to avoid these leaks is to chose another approach to solve your problem.

How come you need a semi-anonymous package instead of, for example, a closure? Those are easy enough to make not leak, and, with some creativity, you can still implement pretty much every external interface on top of them, for example by blessing your closure coderefs and provide methods for them, providing overloading for them, etc.

like image 94
rafl Avatar answered Oct 26 '22 15:10

rafl