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


In reply to Re: Refresh a Module by LanX
in thread Refresh a Module by Timka

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.