in reply to Making a variable in a sub retain its value between calls

Hi, As everyone says, that closure will do the trick. But I cringed since I had trained myself to say whoa there! in such cases, since persistence of a lexical is also a nasty bug if you don't mean it (and perl documentation, some at least, says as much). I think an object is safer, here's one possibility. Also it is easier to maintain.

I'm letting you access the raw value of the counter through hash syntax so you don't need to use Exporter. You could also put everything from package StaticCtr to just before package main into another file, StaticCtr.pm (end it with 1;). Then you can use StaticCtr; in any of your programs.

The new subroutine could be just a line really, it is longer so you can play with it more (see the perlobj manual).

#!/usr/bin/perl package StaticCtr; sub new { my $this = shift; my $class = ref($this) || $this; my $self = {}; bless($self, $class); $self->{ctr} = 0; return $self; } sub inc { my $self = shift; $self->{ctr}++; return $self->{ctr}; } package main; my $c = new StaticCtr; for (1..6) { print " incremented to: " . $c->inc . "\n"; } print "Final value is " . $c->{ctr} . "\n";
This prints:
[mattr@taygeta perlmonks]$ ./ctr.pl incremented to: 1 incremented to: 2 incremented to: 3 incremented to: 4 incremented to: 5 incremented to: 6 Final value is 6

Replies are listed 'Best First'.
Re^2: Making a variable in a sub retain its value between calls
by ikegami (Patriarch) on Apr 19, 2005 at 22:48 UTC

    Unforuately, a reference to the object must be passed to the function, and the OP explicitely requested that the solution didn't do this. I do like passing a state object as you suggest, though. There's much less hidden mojo that way.

    Sorry for this banal reply. The original version of it was completely wrong.

      Ah, my bad.
      I was a little confused what he was getting at. Also was thinking "well you could use a global but that would not be so elegant.." etc. I guess there is a good time to use closures like above.
      Thanks!
      Matt