As part of the big counter example project, this example runs on the command line and uses a plain text file as back-end database
.
It is probably the most basic version of all the counter examples, that provides a single counter.
Front-end
The front end is the command line. We just run the script as perl counter.pl
.
Back-end
In this example the "database" is going to be a simple file called 'counter.txt' with only a number in it. The most recent value of the counter.
Code
use strict;
use warnings;
my $file = 'counter.txt';
my $count = 0;
if (-e $file) {
open my $fh, '<', $file or die "Could not open '$file' for reading. $!";
$count = <$fh>;
close $fh;
}
$count++;
print "$count\n";
open my $fh, '>', $file or die "Could not open '$file' for writing. $!";
print $fh $count;
close $fh;
After the initial statements to enable strict and warnings, we have declared a variable called $file
that holds the name of the 'database' file we are going to use to store the latest value of the counter. This could be declared as a constant or read-only variable, but I did not bother.
During the execution of the script we will hold the value of the counter in the variable we cunningly called $counter
. We declare it up-front and assign a default value of 0 to it.
Next we should be reading in the previous value of the counter. However, before we run the script for the first file, the file holding the number does not exist. Hence we need to do two things.
- When we declare
$counter
using themy
keyword we also initialize it to the default value of 0. This way, even if thecounter.txt
file does not exist yet we can pretend that the previous value 0. - Then, before we attempt to open the
counter.txt
file for reading, we check if it already exists using the-e
operator.
Because at the first run the file does not exist, let's skip this code now and let's go straight to the part after the closing curly brace (}
).
$count++;
print "$count\n";
open my $fh, '>', $file or die "Could not open '$file' for writing. $!";
print $fh $count;
close $fh;
Using ++
the auto-increment operator of Perl, we increment the value of $count
(which started out as 0 during the first execution). Then we print it out to the screen.
In the 3 lines after that, we open the 'counter.txt' file for writing. In the first run this will create the file,
in subsequent runs this will clean up the file to have no content. Then we use the print
statement to write the new content of $count
into the now empty file.
Finally, just to be nice, we close the file handle using the close
function.
On the second and later executions of the script, the 'counter.txt' file will already exist. Thus the if (-e $file)
will return true, and we enter the block:
if (-e $file) {
open my $fh, '<', $file or die "Could not open '$file' for reading. $!";
$count = <$fh>;
close $fh;
}
In this block we try to open the file for reading using the open
function and throw an exception by calling the die
function if we still cannot open the file. This should happen only in the most extreme situation and therefore it is ok to take drastic steps. If the open
was successful, $fh
, the newly declared variable will have the file handle in it. We can then use the <$fh>
operator to read one line (the only one it has) from the file and finally we close
the file.
No need to initialize the counter
Actually when we declared the $counter
variable it was not really necessary to also assign 0 to it. It looks better for people coming from other programming languages, but in Perl even if we left it undef the script would work perfectly well.
That's because when using the ++ auto increment operator on a variable that has undef
in it, that undef
will act as if it was actually 0. It is probably the simplest form of autovivification in Perl. So we could have written
my $counter;