Perl Weekly Challenge 028: File Content and Digital Clock

File Content

Write a script to check the file content without explicitly reading the content. It should accept file name with path as command line argument and print “The file content is binary.” or else “The file content is ascii.” accordingly.

Frankly, I had no idea how to solve this. I had to google the solution, and I was quite surprised Perl had the operators designed for exactly this purpose. During my approximately 20 years of Perl programming, I’ve never needed the -T and -B operators—probably because all my scripts and programs expect either a text or a binary file as the input, and it’s upon the user to provide it in the expected format.

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

say 'The file content is ', (-T shift) ? 'ascii' : 'binary', '.';

Digital Clock

Write a script to display Digital Clock. Feel free to be as creative as you can when displaying digits. We expect bare minimum something like “14:10:11”.

I decided to use Time::Piece to get the current time, and Tk to display the clock.

Tk is an old GUI library. It looks a bit old-school nowadays, but I still prefer it for local applications.

#!/usr/bin/perl
use warnings;
use strict;

use Time::Piece;
use Tk;

Let’s store the current time in a variable with file scope.

my $time;
sub init_time { $time = localtime->strftime('%H:%M:%S') }

localtime here is coming from Time::Piece and returns an object whose strftime method can be used to format the time.

Most Tk applications start by instantiating a MainWindow. Note that the code just declares the object, nothing is displayed until we call the MainLoop which usually happens at the very end of the program.

my $mw = 'MainWindow'->new(-title => 'Digital Clock');

$mw->Label(-textvariable => \$time,
           -font         => 'Arial 48',
)->pack;

The main window will contain a label that will display the variable $time in the given font. The pack method just specifies how the label should be placed in the main window.

Now, let’s have some fun. We’ll update the time label periodically, but we’ll let the user change the frequency of the refresh. To schedule a periodic action, Tk provided the repeat method. It returns an identifier of the action which we can later use to change the interval.

my $rate = 500;  # milliseconds
my $repeat_id = $mw->repeat($rate, \&init_time);

We now want to allow the user to change the rate. We’ll use the Scale widget, its -command attribute contains a callback to be called on each change of the its value: we’ll use it to update the refresh rate.

my $scale = $mw->Scale(-label   => 'Refresh rate:',
                       -orient  => 'horizontal',
                       -from    => 1,
                       -to      => 2000,
                       -command => sub {
                           $repeat_id->time($rate = $_[0]) },
)->pack;
$scale->set($rate);

Now we just need to initialise the time and start the loop.

init_time();
MainLoop();

1 Comment

Pedantically, the definition for the "-T" operator says:

File is an ASCII or UTF-8 text file

So printing "The file content is ascii" is potentially inaccurate :-)

Leave a comment

About E. Choroba

user-pic I blog about Perl.