in reply to Re^4: How to access a variable inside subroutine?
in thread How to access a variable inside subroutine?

It isn't a problem with state.

It's only a problem with my because a new SV is allocated for each call of the outer sub, but the inner sub only closed over the first one.

Replies are listed 'Best First'.
Re^6: How to access a variable inside subroutine?
by LanX (Saint) on Sep 06, 2020 at 09:42 UTC
    In this case maybe, I'm sure one can also produce such problems with state.

    A named subroutine is created at compile time, putting them into other subs or loops means begging for trouble.

    I've never been a big fan of state, there are not many patterns (if any) which can't be implemented with closed over my declarations.

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

      Oh yes, for sure defining one named subroutine within another is almost never what you want. The following is a much clearer way to do things.

      use v5.30; use strict; use warnings; { my $add = 0; sub getter { $add } sub counter { my @nums = (1..500); for my $num (@nums) { $add += $num; } } } counter(); say "getter => ", getter();

      Though, just returning a value from counter() seems better practice:

      use v5.30; use strict; use warnings; sub counter { my $add = 0; my @nums = (1..500); for my $num (@nums) { $add += $num; } return $add; } my $got = counter(); say "got => ", $got;

      I've never been a big fan of state, there are not many patterns (if any) which can't be implemented with closed over my declarations.

      The state keyword is mostly just syntactic sugar. The following are essentially the same:

      { my $foo = 123; sub myfunc { ...; } }
      sub myfunc { state $foo = 123; ...; }

      The latter allows you to eliminate a level of nesting. Also in the case where the value being assigned to $foo is expensive to calculate, it means you won't need to calculate it until myfunc is actually called (which might be never in some cases). If you don't care about undef/false values, you can kind of emulate that using:

      { my $foo; sub myfunc { $foo ||= 123; ...; } }
        defining one named subroutine within another is almost never what you want.

        Definitely. Mine was more a, "hmm, would this work? Yes? Cool!". My original intent was to add caveats, but those never made it in to the post.

        Thank you.