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

Hi, monks.

I wrote kinda code reloader for a framework. Before reloading of modified code I want to "unload" already loaded code so I should clean a package. I'm doing it this way:

my $e = \%{ $package . '::' }; %$e = map { $_ => $e->{$_} } grep { /::$/ } keys %$e;

$package is the name of "unloading" package.

It works with current versions of Perl but I'm wonder is there any problem with this code that can potentially break it in future?

Thanks and sorry for my English.

Replies are listed 'Best First'.
Re: What is the correct way to clear package?
by ikegami (Patriarch) on May 05, 2011 at 20:15 UTC

    For future compatibility, deleting should be safer than setting.

    my $pkg = \%{ $pkg_name . '::' }; delete $pkg->{$_} for grep !/::\z/, keys %$pkg;

    Update: Or even

    my $pkg = \%{ $pkg_name . '::' }; delete @{$pkg}{ grep !/::\z/, keys %$pkg };
      I've tried delete but for some reason it doesn't work fine with "use base" after reloading.
Re: What is the correct way to clear package?
by Anonymous Monk on May 06, 2011 at 03:47 UTC

      Thanks! It works for me.

      Update:

      No, it doesn't.

      It clears nested packages. It's not required behavior.

      #!/usr/bin/env perl package Test1; package Test1::Nested; sub a { print "Test1::Nested::a\n"; } package main; use Symbol; # ok. eval "Test1::Nested::a()"; die $@ if $@; Symbol::delete_package( 'Test1' ); # fails. eval "Test1::Nested::a()"; die $@ if $@;
        > It's not required behavior.

        Well, it's not our fault if you don't clarify your requirements... It was a struggle to find out what you exactly want.

        > It clears nested packages.

        2 Thoughts:

        1. Symbol::delete_package is plain perlcode, you could just adapt it to your needs.
        2. If you want to rely on Symbol been kept adapted to any future changes, why not just safe away the globs of nested packages, apply delete_package() and then reassign the globs? You already have the necessary code in the OP.

        Cheers Rolf

Re: What is the correct way to clear package?
by LanX (Saint) on May 05, 2011 at 18:48 UTC
    I'm confused, for me it looks like you are just assigning the old values back.²

    And if IIRC nested packages are hold in the %main:: stash.¹

    So either your example is wrong or I'm lacking enough understanding of whats going on.

    Cheers Rolf

    1) wrong, I misunderstood perlmod

    { package ding::dong; $x=1 } $\="\n"; print $ding::dong::x; # prints 1 print $main::{"ding::"}; # *main::ding:: print $main::{"ding::"}->{"dong::"}; # *ding::dong:: print $main::{"ding::"}->{"dong::"}->{x}; # *ding::dong::x

    2) AHH now I got it... you're just keeping the sub packages (here "dong::" of "ding::") and cleaning anything else.