in reply to Refresh a Module

To sum the thread up:

Question 1: why does the undef statement makes the next require fail?

Like already explained, it's the delete of the typeglob aka symbol which is causing the problem,

This works for me

use lib '.'; use My; eval "My::Run('eval')"; My::Run('normal'); delete $INC{"My.pm"}; # --- Why do this? undef &My::Run; # 1. Avoids warning redefined # 2. will deactivate function if missing in new module # --- Why DON'T do this # delete $My::{Run}; # If you destroy the symbol, Perl won't know how to handle optimies op +code require My; eval "My::Run('eval')"; My::Run('normal');

---- Loading My at 1727478470.8689 ... Running Run(eval) loaded at 1727478470.8689 Running Run(normal) loaded at 1727478470.8689 ---- Loading My at 1727478470.87299 ... Running Run(eval) loaded at 1727478470.87299 Running Run(normal) loaded at 1727478470.87299

Question 2: How to reload a module without having to use an eval (like eval "My::Run()")

IMHO both, normal call and eval should work. Also importing symbols.

The following solution seems to work and should probably be a module on CPAN.

Basic idea is to never use use from the beginning. I.e. don't load at compile time. Use runtime "reuse" at the beginning of execution.

Like that the calls in the OP-Code will never optimize to refs and hence always check the symbols in the STASH, without weird side-effects.

use v5.12; use warnings; use lib "."; ReUse::reuse("My" => 1,2,3); My::Run("normal"); eval 'My::Run("eval")'; ReUse::reuse("My" => 1,2,3); My::Run("normal"); eval 'My::Run("eval")'; package Test; my $data = [1..5]; say "\n\n---- ReImporting from module"; ReUse::reuse("Data::Dump" => qw/pp/); pp($data); # test import say "\n\n---- ReImporting from module"; ReUse::reuse("Data::Dump" => qw/pp/); pp($data); # test import exit; # --- this should probably be a proper CPAN Module package ReUse; sub reuse { my ($module, @imports) = @_; # --- purge %INC my $inc_key = "$module.pm"; $inc_key =~ s(::)(/)g; my $oldpath = delete $INC{$inc_key}; # --- build code # --- require at runtime my $PACKAGE = (caller)[0]; my $REQUIRE = $inc_key; eval <<"__CODE__"; package $PACKAGE; require "$REQUIRE"; __CODE__ if ($@) { die qq(REQUIRE of "$module" failed with: <$@>); } # --- import at runtime my $IMPORTS = join ",", map {"'$_'"} @imports; eval <<"__CODE__"; package $PACKAGE; $module->import($IMPORTS); __CODE__ if ($@) { die qq(IMPORT OF "$module->import($IMPORTS)" failed with: <$@> +); } # --- warn if module's path changed # TODO make optional if ($oldpath and $oldpath ne $INC{$inc_key}) { # untested TODO warn "Path of $module changed"; } }

---- Loading My at 1727477140.49975 ... Running Run(normal) loaded at 1727477140.49975 Running Run(eval) loaded at 1727477140.49975 ---- Loading My at 1727477140.50415 ... Running Run(normal) loaded at 1727477140.50415 Running Run(eval) loaded at 1727477140.50415 ---- ReImporting from module [1 .. 5] ---- ReImporting from module [1 .. 5]

NB: I didn't bother to purge the old STASH with the old symbols to have a clean start, because:

ATM I think deleting the namespace and/or undef-ing the subs and vars should be optional and decided by the user.

Last but not least: my My.pm (put in the same dir like above code).

package My; use v5.12; use warnings; no warnings "redefine"; use Time::HiRes qw(time); my $loadtime = time(); say "\n\n---- Loading " . __PACKAGE__ . " at $loadtime ... "; sub Run { say "Running Run(@_) loaded at $loadtime" }

HTH

Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^2: Refresh a Module
by Timka (Acolyte) on Oct 01, 2024 at 03:38 UTC

    Besides the perl5 c/h mainly repo,

    Would I find these esoteric feature in a perldoc page?

    (Thanks everyone btw to your much provided input and enlightenment.)

      First of all "refreshing a module" makes as much sense as "refreshing a family", it's not simply done by remarrying another partner.

      You're the one who has to deal with the resulting patchwork. ( Unless you took care to have a very limited relation without kids and common property. Or unless you think you can still show up with a spare key and sleep in the old bed and you don't care about the mess ... Etc... etc ...)

      I discussed it with my local group and everybody had another understanding what refreshing a module is supposed to engulf. I begged you to clarify what you want, alas you didn't.

      Secondly there is a reason why implementation details remain undocumented features:

      > Since the suppliers of the software usually consider the software documentation to constitute a contract for the behavior of the software, undocumented features are generally left unsupported and may be removed or changed at will and without notice to the users

      Thirdly I already pointed you to documentation and listed the keywords. Most is found in perlsub and perlmod and my code was based on it.

      Now if you just copy code you don't understand from modules meant for different ends and using undocumented features , ...

      ... Well then you shouldn't complain! :)

      Deleting the stash is like burning down the marriage registry. It's still bigamy if you marry again.

      Simply copying expert code doesn't make you smarter. Especially if the original authors had other goals in mind and your goals are fuzzy.

      Happy reading of the docs. :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery