in reply to Re^2: Array ending up empty when processing more than a single file
in thread Array ending up empty when processing more than a single file

Well for the same reason as my example, the inner sub is only applied once, so only the second sub is a redefinition.

I didn't find where the fact that a given definition of a sub (except anonymous of course) will only be applied once, no matter how often the scope of its definition is entered (actually I don't think the place where a function is defined matters at all, except for namespace and during compilation), but Lexical Subroutines explains how to create what you might expect (lexically scoped function, with redefinition each time), and so implies that the normal behaviour is different.

  • Comment on Re^3: Array ending up empty when processing more than a single file

Replies are listed 'Best First'.
Re^4: Array ending up empty when processing more than a single file
by LanX (Saint) on Oct 05, 2017 at 17:35 UTC
    I'm confused ... isn't this the old "won't stay shared" discussion?

    Named subs are defined at compile time, that's why you can call a sub which is defined later.

    A closure can only "share" the set of closed over variables it sees at definition time.

    (i.e. name and reference are added to the "lexical pad" compare PadWalker)

    That's why nesting named subs are discouraged in Perl.

    edit

    But when using an anonymous sub, the definition happens at run time.

    something like

     *name = sub {...} would solve this.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

      You are completely correct. I was being dense. :P

      >perl -wle 'for(1,2){ eval "sub moo{}" }; sub moo{};' Subroutine moo redefined at (eval 1) line 1. Subroutine moo redefined at (eval 2) line 1.

      I guess that's actually the reverse discussion. There's just no "warning, the variable WILL stay shared" :-P

        As I said: I'm confused...

        > There's just no "warning, the variable WILL stay shared" :-P

        There might be no warning, but it's still the same problem.

        You proved that from the second run on $var isn't shared anymore.

        Just a minor change to your code, and the warning appears:

        use strict; use warnings; $\ = $/; tst() for (1..2); sub tst { my $var = 1; print \$var, " created"; sub func { print \$var; } func(); }
        Variable "$var" will not stay shared at d:/pm/wont_stay_shared.pl line + 13. SCALAR(0x4c97f0) created SCALAR(0x4c97f0) SCALAR(0x4a8420) created SCALAR(0x4c97f0)

        Looks like you found a case insufficiently covered by warnings!

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!