in reply to Refresh a Module

A function call does the stash lookup when it's compiled, and compile time inside the eval (and consequently require) is runtime.

Deleting the Stash entry after the call is compiled doesn't help, because the reference is cached.

But you can always redefine/redeclare the sub. An already compiled call will execute the new code.

If you are looking for a way to destroy a sub in a way to make an already compiled call break, I'm very sceptical about the wisdom of this concept.

FWIW: you can also try delete $::{'My::'} to delete the whole package. But this won't touch already referenced elements, resp. compiled calls.

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

Replies are listed 'Best First'.
Re^2: Refresh a Module
by LanX (Saint) on Sep 26, 2024 at 15:06 UTC
    > Deleting the Stash entry after the call is compiled doesn't help, because the reference to the typeglob is cached.

    Ran a quick test on my phone:

    Looks like the typeglob˛ is looked up and the reference is stored in the OP tree. See \&main::t in #4.

    That's why further manipulation will produce different results if the original typeglob isn't targeted. °

    (Concise is able to backengineer the original name or is doing other introspection)

    ~ $ perl -MO=Concise -e'sub t {}; t()' 6 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter v ->2 2 <;> nextstate(main 3 -e:1) v:{ ->3 5 <1> entersub vKS ->6 - <1> ex-list K ->5 3 <0> pushmark s ->4 - <1> ex-rv2cv sK/1 ->- 4 <#> gv[IV \&main::t] s ->5 -e syntax OK

    For comparison, that's what's happening when the sub is unknown at compile time

    gv[*t] which most likely means "look up the symbol t at runtime"...

    ~ $ perl -MO=Concise -e't();' 6 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter v ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 5 <1> entersub[t2] vKS/TARG ->6 - <1> ex-list K ->5 3 <0> pushmark s ->4 - <1> ex-rv2cv sK/1 ->- 4 <#> gv[*t] s/EARLYCV ->5 -e syntax OK ~ $

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

    °) especially deleting the entry in the namespace prevents the compiler to find the old typeglob.

    ˛) or is it only the CODE slot? How reliable is concise here???

Re^2: Refresh a Module
by Danny (Chaplain) on Sep 25, 2024 at 23:25 UTC
    Can you elaborate or provide a reference? It's still unclear to me why My::Run() doesn't get redefined here:
    require My; print "a: "; My::Run(); # a: Running undef &My::Run; require My; print "b: "; My::Run(); # Undefined subroutine &My::Run called at ...
      Well yes, undef &sub is a way to destroy a sub. Again I doubt the wisdom of doing so.

      I'll try to come up with some example code tomorrow...°

      Though others might be faster ;)

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

      °) My guess is that most of the confusion is caused by the deletes in the stash

        Actually, in my example I forgot to delete $INC{"My.pm"}; so the second require wasn't redefining My::Run. When I add the delete it works as expected, printing:
        Loading... a: Running Loading... b: Running
        In the OPs example there is also a delete $My::{Run}. So
        require My; print "a: "; My::Run(); # a: Running undef &My::Run; delete $INC{"My.pm"}; delete $My::{Run}; require My; print "b: "; My::Run(); # Undefined subroutine &My::Run called at ...
        says My::Run() is undefined in the second call. What does delete $My::{Run} do?
        Why bother with un defining a sub when you can just delete it? 🤔