bigmoose has asked for the wisdom of the Perl Monks concerning the following question:

Hi Everyone

If I have some code where I want to call a sub routine and increase a variable within it each time I call it, how would I do that?

So for example... the below is how i tought it would work.. pseudo code style!..

run = 1 while (run == '1') { print increaseNumber(); } sub increaseNumber { my $value = 001 return $value + 1 }; ###which would print### 001 002 003 ###etc###

feel like im struggling because i'm not aware of a concept.. please help!

Replies are listed 'Best First'.
Re: increasing value every time sub routine called
by BrowserUk (Patriarch) on Dec 09, 2011 at 12:39 UTC
    sub increaseNumber { my $value = 001 return $value + 1 };

    Every time you call that sub, you (re)set $value to one.

    If you did it this way:

    my $value = 1; sub increaseNumber { return ++$value; };

    It would work as you want.

    Why post pseudo-code rather than proper Perl?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

      I worked it out :)

      increase(); increase(); increase(); sub increase { $n += 1; # Global variable $n print "$n\n"; }
Re: increasing value every time sub routine called
by Fox (Pilgrim) on Dec 09, 2011 at 12:48 UTC
    well, if you really want to do this:
    use feature "state"; sub a { state $i++; print $i; } a(); a(); a();
    prints 123
Re: increasing value every time sub routine called
by johngg (Canon) on Dec 09, 2011 at 16:22 UTC

    Have a look at sprintf for your leading zeros. Others have mentioned closures or subroutines incrementing a global variable. IMHO a closure is tidier, obviating the need for a global that might accidentally get tinkered with elsewhere in the code.

    knoppix@Microknoppix:~$ perl -Mstrict -wE ' > my $rcIncrement = do { > my $value = 0; > sub { return sprintf q{%03d}, ++ $value }; > }; > > say $rcIncrement->() for 1 .. 3; > say q{-} x 10; > say $rcIncrement->() for 1 .. 3;' 001 002 003 ---------- 004 005 006 knoppix@Microknoppix:~$

    I hope this is helpful.

    Cheers,

    JohnGG

Re: increasing value every time sub routine called
by jethro (Monsignor) on Dec 09, 2011 at 12:56 UTC

    the concept you are looking for is called a closure

      No, he doesn't. He isn't asking for multiple instances of counters. A single subroutine with an external variable (or an internal state variable) will do.
      sub next_number {no warnings;++$::N} say next_number; say next_number; say next_number; __END__ 1 2 3
        Well in perl land, a single (named) subroutine with a (lexical) external variable is still classed as a closure.

        Dave.

Re: increasing value every time sub routine called
by TJPride (Pilgrim) on Dec 09, 2011 at 19:16 UTC
    Just keep in mind that the variable declaration only happens if you call the sub after it's been declared, so you either need to "use" the function or call it from below, like in my example:

    use strict; use warnings; { my $persistent = 0; sub increment { print ++$persistent; }} increment(); increment(); increment();