in reply to Why is it uninitialized?

I believe you've inadvertantly created something akin to a closure (except it's not anonymous), and perl is using the current value (undef) of the lexical variable $S4 when the subroutine is defined. The variable needs to have package-level scope (which our $S4 gives you; aka "global") in order to be "live" in the subroutine. Or, better, pass it as a parameter to the function.

Some of this is hinted at in perlsub, search for the first instance of "closure", and perlref. You can read those statements in the docs without realizing the implications, until you actually run across a bug that helps it solidify.

Replies are listed 'Best First'.
Re^2: Why is it uninitialized?
by dave_the_m (Monsignor) on Dec 20, 2017 at 18:53 UTC
    something akin to a closure (except it's not anonymous)
    In perl, a closure doesn't have to be an anonymous sub; any sub that uses lexical variables which are declared in a scope outside that sub, closes over those vars at the time the sub is created. Anonymous subs are usually more interesting, since multiple instances of the sub are often created at runtime, thus capturing multiple instances of outer lexicals. Conversely, named subs are created just once, at compile time, thus just capturing the first instance of each lexical.

    Dave.

Re^2: Why is it uninitialized?
by Laurent_R (Canon) on Dec 20, 2017 at 19:00 UTC
    Although this is almost slightly off-topic, please note that a closure doesn't have to be anonymous (but closures are quite commonly anonymous).

      ++Laurent_R ++dave_the_m: yeah, I didn't originally think it had to be anonymous, but perlref said "Closure is a notion out of the Lisp world that says if you define an anonymous function in a particular lexical context, it pretends to run in that context even when it's called outside the context." Maybe I'm just misinterpreting that (maybe always anon in Lisp? dunno). Or maybe the doc wasn't worded as carefully as it could have been. Thanks for the clarification.

        I did not have time before. Just a short example of a named closure (an iterator) at the command line:
        $ perl -e 'use feature "say"; > { my $number = 0; > sub supply_square { > $number ++; > return $number ** 2; > } > } > say supply_square for 1..5; > say supply_square for 1..5; ' 1 4 9 16 25 36 49 64 81 100