johnnywang has asked for the wisdom of the Perl Monks concerning the following question:

This is a follow up on the discussion in keys %::. Since the "package Foo;" statement introduces an entry in the main symbol table $::{'Foo::'} as well as its typeglobed value %Foo::, it seems that if I delete this entry explicitly, then one should not be able to do "Foo->new()", and the Foo symbol table should be gone also. The following code confirms the first, but it seems the %Foo:: still exists, why is that?
# test.pl use strict; package Foo; sub new{ return bless {}, shift; } sub foo{ my $self = shift; print "Foo called\n"; } package main; # print the full symbol table, notice the Foo:: entry print "$_ => $::{$_}\n" foreach keys %::; print "\n\n"; delete $::{'Foo::'}; # shouldn't this delete the symbol table for Foo? # print again the full symbol table, notice Foo:: is gone. print "$_ => $::{$_}\n" foreach keys %::; print "\n\n"; # seems still there. print "$_ => $Foo::{$_}\n" foreach keys %Foo::; print "\n\n"; # but can't call the following, as expected my $f = new Foo(); $f->foo();
On cywin, the result is (removed some entries to make it shorter):
" => *main::" CORE:: => *main::CORE:: strict:: => *main::strict:: $ => *main::$ Foo:: => *main::Foo:: main:: => *main::main:: => *main:: @ => *main::@ <none>:: => *main::<none>:: " => *main::" CORE:: => *main::CORE:: strict:: => *main::strict:: $ => *main::$ main:: => *main::main:: => *main:: @ => *main::@ <none>:: => *main::<none>:: foo => *Foo::foo new => *Foo::new Can't locate object method "new" via package "Foo" (perhaps you forgot + to load " Foo"?) at test.pl line 30.

Replies are listed 'Best First'.
Re: Directly remove an entry from the symbol table
by tlm (Prior) on May 03, 2005 at 11:41 UTC

    FWIW, if you replace the last two lines of your script with

    my $f = $Foo::{'new'}->( 'Foo' ); $Foo::{'foo'}->( $f );
    ...it runs without error. I am not 100% sure I understand your question, but if you are asking why manually removing the Foo entry in main's symbol table does not result in the automatic destruction of the Foo typeglob, I don't see any a priori reason why this should be the case.

    the lowliest monk

Re: Directly remove an entry from the symbol table
by PodMaster (Abbot) on May 03, 2005 at 06:13 UTC
    Try
    my $z = new Foo::(); $z->foo();

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Directly remove an entry from the symbol table
by osunderdog (Deacon) on May 03, 2005 at 14:44 UTC

    Have you looked at:

    use Symbol qw|delete_package|;

    Here's the chunk I used:

    eval { delete_package($packageName); # Have to remove the package from the %INC hash so that require wi +ll # actually load the package again. delete($INC{$packageFile}); };

    I can't say that I ever got package dropping to work 100%. It doesn't free up memory for the package.

    Hope this helps.

    Soon to be unemployed!