Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

best way to keep a simple count?

by Cody Pendant (Prior)
on Apr 11, 2005 at 10:37 UTC ( [id://446555]=perlquestion: print w/replies, xml ) Need Help??

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

I was in a situation the other day where I just wanted to keep a count between iterations of a program.

Something like the auto-increment facility of a database, and I could use a database, but it seems like overkill. I'd have a table with one column with one INT in it.

All I want to do is save 99 on a Monday, and when I run my program again on Tuesday, pick up the 99, increment it to 100 and save 100 back.

What would monks do? Lock and read a simple text file with the digits in it? Use dbmopen()? Store the number using a module?



($_='kkvvttuu bbooppuuiiffss qqffssmm iibbddllffss')
=~y~b-v~a-z~s; print

Replies are listed 'Best First'.
Re: best way to keep a simple count?
by rob_au (Abbot) on Apr 11, 2005 at 10:54 UTC
    For a proven wheel for this solution, take a look at File::CounterFile - It's not just for web counters! :-)

     

    perl -le "print unpack'N', pack'B32', '00000000000000000000001000000000'"

Re: best way to keep a simple count?
by tlm (Prior) on Apr 11, 2005 at 13:51 UTC

    You could use Inline::Files and store the counter with the script itself.

    the lowliest monk

Re: best way to keep a simple count?
by monkfan (Curate) on Apr 11, 2005 at 12:44 UTC
    Advices I got from experts:
    open I, "<counter.txt"; my $n = <I>; chomp($n); close(I); $n++; open O +, ">counter.txt"; print O $n; close(O);
    or
    Storable::nstore("file", \$count);
    or using File::Slurp
    perl -MFile::Slurp -le 'write_file "tmp42", $n = 1 + eval{read_file "t +mp42"}; print $n'
    Regards,
    Edward

      Some experts gave you bad advice. You need to read and update the file as one step, otherwise another process comes along and tries to do the same thing while you are in the middle. Either the count doesn't get incremented properly (both processes read the same value before either one wrote a new one), the count gets reset (one process reads the file just after it was truncated), or the count disappears.

      --
      brian d foy <brian@stonehenge.com>
Re: best way to keep a simple count?
by willyyam (Priest) on Apr 11, 2005 at 12:47 UTC

    I'm a sucker for log files, so I would probably capture the date and time of the program's run, perhaps its arguments (if any) on one line of a log file. Then, I could just run wc -l /logfile for a count, but then I can capture other information as well.

Re: best way to keep a simple count?
by Anonymous Monk on Apr 11, 2005 at 12:03 UTC
    Been there, done that, did it in many ways. I've used a database, I've used locked files, I've used plain unlocked files open for read/write and used seek, and I've echoed new numbers to files.

    What is "best" purely depends on what you want, and what your wishes are. All solutions are simple, requiring just a few lines of code.

Re: best way to keep a simple count?
by mattr (Curate) on Apr 11, 2005 at 14:36 UTC
    I second the recommendation of File::CounterFile, it just works. I've used it a number of times in the past. Matt
Re: best way to keep a simple count?
by salva (Canon) on Apr 11, 2005 at 14:47 UTC
    use a Config::* module that allows writting:
    #!/usr/bin/perl use warnings; use strict; use Config::Properties::Simple; my $cfg=Config::Properties::Simple->new(scope=>'user', optional=>1); my $count=$cfg->getProperty(counter => 0); print "counter: $count\n"; $cfg->setProperty(counter => ++$count); $cfg->save;

    You should also use some lock to ensure that only one process reads and increments the counter.

Re: best way to keep a simple count?
by davidrw (Prior) on Apr 11, 2005 at 15:55 UTC
    yet another way (not necessarily the best) would be Cache::FileCache (useful for many other things such as caching database query results). One downside (or upside) is you don't (readily--i think it throws it under /tmp/ somewhere) have the filename, so can't do "cat counter.txt" to check it.
    use Cache::FileCache; my $cache = new Cache::FileCache( { namespace=>"my_program", auto_pu +rge_on_get=>1 } ); my $cacheKey = 'ct'; my $value = $cache->get( $cacheKey ) || 0; $value++; $cache->set( $cacheKey, $value, $EXPIRES_NEVER );
Re: best way to keep a simple count?
by Anonymous Monk on Apr 11, 2005 at 13:46 UTC
    From the shell:
    echo $((`cat counter` + 1)) > counter
          echo $((`cat counter` + 1)) > counter

      Which won't work well if there can be multiple instances of the program running at the same time.

        I never claimed it was. And it wasn't the first suggestion in this thread that might fail if multiple instances of the program are running at the same time. (Well, technically, having multiple instances of the program running at the same time isn't the problem - the problem is them executing the one line of code at the same time).

        Code Pendants question was vague. He just wanted to know what other people used. He didn't state anything specific about his situation. Other than the implicite suggestion the program is started once a day (so, no multiple occurences).

        Here's another one-liner you can list faults for:

        perl -pi -le '$_++' counter
Re: best way to keep a simple count?
by Spidy (Chaplain) on Apr 12, 2005 at 20:36 UTC
    Personally, I would just use dbmopen(); because I like it, and it's easy enough.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://446555]
Approved by polettix
Front-paged by monkfan
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-26 04:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found