So I'm new to Perl and I found I wanted to code a countdown, and really struggled, I found some code here http://www.perlmonks.org/bare/?node_id=407922 and tried to figure out what is going but failed in part.
Trouble is I hate using code I do not understand, so was hoping someone would be able to help me out with some parts of it (code below is from URL)
use 5.16.3;
use strict;
my $countdown = 1*60*60; # in seconds
$| = 1;
my $beginTime = time;
my $endTime = $beginTime + $countdown;
for (;;)
{
my $time = time;
last if ($time >= $endTime);
printf("\r%02d:%02d:%02d",
($endTime - $time) / (60*60),
($endTime - $time) / ( 60) % 60,
($endTime - $time) % 60,
);
sleep(1);
}
Below I have numbered and reproduced lines of code where I do not understand them
1: 1*60*60
I understand 60*60, but why the 1?
2: $| = 1;
Not a clue on this
3: for(;;)
Not sure on what the ;;
are doing?
4: No idea what this is doing? (Mathematically or syntactically).
printf("\r%02d:%02d:%02d",
($endTime - $time) / (60*60),
($endTime - $time) / ( 60) % 60,
($endTime - $time) % 60,
Thanks for any help or useful URL's where I could research it myself (have tried this already to no avail)
Good luck with learning Perl. Making sure you understand what's going on is a great way to learn.
The 1
doesn't really do anything from a mathematical or a code point of view. My guess is that the author put it in to make it easier to change to a different number of hours - simply replace the 1
with 2
or whatever.
Perl has loads of "special variables" which affect how things work. You'll probably meet one or two of them but not need the rest until you start doing something complicated. They are all described in the Perl documentation which you can get by typing perldoc perlvar
at your commandline, or looking at this page. In this case $|
is "autoflush", and setting it to 1
means that as soon as you print something it gets sent to the output straightaway. Without this, some buffering might take place. Don't worry too much about it, though.
There are several ways of specifying that a loop should continue indefinitely, or until something like last
stops it. One of these is for (;;)
which is a syntax which comes from C. When you start looking at different sorts of loops, you'll find out a bit more about this. But there are other ways of doing loops in Perl as well.
This is where the maths happens. To find the time difference in hours, the time difference in seconds ($endTime - $time
) is divided by 3600. This is printed using the %d
format of printf
which rounds it down to an integer. So you'll see something like 03:
at the beginning of the output. The next expression takes the time difference in seconds, divides it by 60 to get the time difference in minutes. But if this is more than one hour, the number is going to be greater than 60, so you can't just display this. The Perl modulo functiton is %
and this gives the remainder when you divide again by 60. This gives the number of minutes in the time difference. A similar approach gives the number of seconds. If you're not familiar with printf
you can find details by typing perldoc -f printf
or by looking here.
I hope this starts to make sense for you. Have a play with this, and ask here again with any other questions.