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

The sub keyword will only define the subroutine once

This is interesting and, to me at least, unexpected. Why does this only warn once instead of twice?

perl -wle 'for(1,2){ sub moo{} }; sub moo{}' Subroutine moo redefined at -e line 1.
  • Comment on Re^2: Array ending up empty when processing more than a single file
  • Download Code

Replies are listed 'Best First'.
Re^3: Array ending up empty when processing more than a single file
by Eily (Monsignor) on Oct 05, 2017 at 16:44 UTC

    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.

      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