in reply to static storage in a local subroutine?

Moron,
Good news - Perl6 will scratch that itch. See How will you use state declared variables in Perl6? for more details.

For now, you use scope to accomplish this:

{ my $cnt = 1; sub get_count { return $cnt++; } } print get_count(), "\n" for 1..10;

Cheers - L~R

Replies are listed 'Best First'.
Re^2: static storage in a local subroutine?
by merlyn (Sage) on Nov 23, 2005 at 14:49 UTC
      merlyn,
      You are of course correct. It is better to be safe then sorry. Unfortunately, I am a bit confused as to the behavior of the following:
      #!/usr/bin/perl use strict; use warnings; INITIALIZE: { my $cnt = 1; sub get_count { return $cnt++; } } print get_count(), "\n" for 1..10; goto INITIALIZE if get_count() < 15; __END__ 1..10, 12..21
      Care to elaborate?

      Update: Explanation from tye in the CB
      The re-initialization of $cnt doesn't impact the get_count() sub because it is only defined once at compile time. It however does get re-initialized which may impact other things within the same scope but not in the sub itself. To avoid wasting resources and make the intent clear, using the BEGIN block is a good idea (which I never doubted in the first place).

      Cheers - L~R

Re^2: static storage in a local subroutine?
by jeffguy (Sexton) on Nov 23, 2005 at 13:52 UTC
    I tested your code and am amazed to see it works. I don't understand!! I mean, I understand how to make a closure. But my intuition (which is apparently incorrect) says that sub get_count is redefined each time executing this block, thus capturing a new my $cnt each time. Can someone clear this up -- why doesn't this block redefine sub get_count each time?

    Thanks in advance!
      jeffguy,
      Ok, there are a few things to keep in mind here. The first is that named sub declarations are scoped to the current package. The only way to have a lexical sub is for it to be an anonymous code ref. The second thing to keep in mind is that program flow never returns to a point above the sub declaration to even attempt to redefine the sub - it is a naked block.

      If this doesn't answer your question, ask something a bit more specific. Better yet, play around and see if you can figure it out for yourself.

      Cheers - L~R

        I'm with you now. When I first looked at your code, I was thinking it was a chunk to be embedded in a subroutine, a la
        sub test{ { my $cnt = 1; sub get_count { return $cnt++; } } print get_count(); } print "test 4: ".test(4)."\n"; print "test 7: ".test(7)."\n";
        so I was seeing get_count() should be defined repeatedly.
      • As you point out, since it is named, it is defined only once.
      • *Your* code shows the much more obvious and clear way of doing it -- define get_count() in a block outside any code.

      • Your explanations and examples were very helpful. Thanks a bunch!
      But my intuition (which is apparently incorrect) says that sub get_count is redefined each time executing this block
      No, named subs are only created once, during compilation. Anonymous subs are created each time you ask for one to be created. The lexical capture happens at creation time.

      Dave.