Tag Archives: linux format

Learning from Bad Code

I’ve written before about Linux Format’s habit of sharing badly written Perl code. I thought things were improving, but in the new edition (November 2012, issue 163) they’re back to their old tricks.

This time it’s a tutorial called “Starfield: Learn new languages”. In this tutorial Mike Saunders writes similar starfield simulation code in C, Python and Perl. Mike’s loyalties are made perfectly clear when these three sections are entitled “Low Level”, “High Level” and “Unusual Level” respectively, so I wasn’t expecting much. But here’s what I got.

#!/usr/bin/perl

$numstars = 100;

use Time::HiRes qw(usleep);
use Curses;
$screen = new Curses;
noecho;
curs_set(0);

for ($i = 0; $i < $numstars ; $i++) {
  $star_x[$i] = rand(80);
  $star_y[$i] = rand(24);
  $star_s[$i] = rand(4) + 1;
}

while (1) {
  $screen->clear;

  for ($i = 0; $i < $numstars ; $i++) {
    $star_x[$i] -= $star_s[$i];
    if ($star_x[$i] < 0) {
      $star_x[$i] = 80;
    }

    $screen->addch($star_y[$i], $star_x[$i], ".");
  }

  $screen->refresh;
  usleep 50000;
}

Let’s be clear here. This code works exactly as Mike intended it to. But if you’re writing sample code for other people to learn from, I think you should be setting the bar a little higher than “works for me”. I think you should should be aiming to show people good quality code that can be easily mainitained. And this code falls well short of that aim.

Let’s look at some of the problems in more detail:

  • No use strict or use warnings. Let’s be generous and assume the editor removed them to save space.
  • Undeclared variables. Of course. if the code contained use strict then the variables would all have had to be declared. Not declaring them means that we’re using package variables rather than lexical variables. In code this simple it doesn’t make a difference. But it’s a bad habit to get into.
  • Indirect object notation. When creating the Curses object the tutorial uses the syntax $screen = new Curses. Again, not a problem in this program, but a really bad habit to be encouraging. In the article’s defence, the documentation for the Curses module only includes this flawed syntax.
  • Split data structures. The author of the article says “instead of having an array of stars containing coordinates and speeds for each one (i.e. an array of arrays), to make things simpler we’ve just set up three arrays.” I read this to mean “I’ve never been able to work out how to make arrays of arrays work in Perl so I’ve taken the easy way out.” This is, of course, a terrible idea. Linked data items should be stored in the same data structure.
  • C-style for loops. The mark of a C programmer who never really got to grips with Perl. The C-style for loop is rarely used in Perl code. The foreach loop almost always leads to more readable code.
  • Magic numbers. The size of the screen and the maximum speed of the stars appear as numbers in the code. Even if you’re not a Perl programmer, surely you would know that it’s good practice to move those into variables or constants.

With all that in mind, here’s my version of the program.

#!/usr/bin/perl

use strict;
use warnings;

use Time::HiRes qw(usleep);
use Curses;

my $numstars = 100;
my $screen_x = 80;
my $screen_y = 24;
my $max_speed = 4;

my $screen = Curses->new;
noecho;
curs_set(0);

my @stars;

foreach my $i (1 .. $numstars) {
  push @stars, {
    x => rand($screen_x),
    y => rand($screen_y),
    s => rand($max_speed) + 1,
  };
}

while (1) {
  $screen->clear;

  foreach my $star (@stars) {
    $star->{x} -= $star->{s};
    $star->{x} = $screen_x if $star->{x} < 0;

    $screen->addch($star->{y}, $star->{x}, '.');
  }

  $screen->refresh;
  usleep 50000;
}

What do you think? Is it more readable? Easier to maintain? Are there any problems or improvements that I’ve missed?

Yet More Modern Perl in Linux Format

Over the weekend the postman bought me my subscribption copy of Linux Format issue 155. This contains the third (and final) part of my Modern Perl tutorial. In this part we’re adding features to the Dancer web application that we started in issue 153.

This series has concentrated on web applications (with Dancer) and database access (with DBIx::Class). I’ve already got provisional agreement for another short series later in the year – where I plan to cover OO programming using Moose.

The new issue will be in the shops later this week.

Free Training Competition in Linux Format

I’ve mentioned before that I’m running some public training courses in London next month. But how do you fancy coming along to those courses for free?

Those lovely people at O’Reilly have put an advert for the courses in the new issue of Linux Format which hits the shops about now. That’s issue 154 and the advert is on page 54. The advert contains details of a competition where two people can win free places on the two courses – one person on each course.

There are also four runner-up prizes which are copies of the new edition of the Camel book.

All you need to do is… well to find that out you’ll need to buy the magazine. Ok, so entry isn’t 100% free – you’ll need to pay £6.49 for the magazine.

More Modern Perl in Linux Format

Yesterday’s post bought my subscription copy of Linux Format issue 153. This issue contains the second article in my short series about Modern Perl. In this article we take the simple DBIx::Class application that we wrote last time and put a web front end on it using Dancer.

Over the next few days I’ll be writing the third (and final) article in the series. This will involve adding more features to the web app.

If the series is successful (and please let LXF know if you liked it) then perhaps I’ll be asked back to write more next year.

LXF 153 should be appearing in all good newsagents next week.

Modern Perl in Linux Format

A couple of times, I’ve complained here about the standard of Perl articles in the British magazine Linux Format.

Following the second of those articles I got into a discussion with Graham Morrison, the editor of the magazine and he offered me the opportunity to improve matters by writing my own short series of tutorials for them.

The first of those tutorials appears in issue 151 of the magazine which will be appearing in UK newsagents about now.

The series is called “Modern Perl” (in an attempt to distance it from their earlier tutorials) and the first article is about how easy it is to write a database application using DBIx::Class. The second article will take the same database and build it into a simple web application using Dancer. That will hopefully be in issue 153 (skipping an issue). There will probably be a third article in the series which will add features to the web application.

I’ll find out what my rights are to the articles and hopefully I’ll be able to put them on the web at some point in the future.

If you see a copy in your newsagents then please consider picking it up. And if you enjoy the article, then please let the magazine know.

An Open Letter to Linux Format

Back in September 2010 I wrote a piece criticising the way that Perl had been described in a recent issue of Linux Format. In a response to my article, the editor wrote:

And, believe it or not, I do care about Perl. I met Paul Fenwick a few months ago, and he agreed to write a Perl tutorial series for us – I hope you agree with my choice!

So when I saw that a new series of Perl tutorials was starting in the “Coding Academy” supplement of the new issue (#149, June 2011) I was looking forward to reading a useful introduction to the language written by Paul Fenwick.

Unfortunately, I was disappointed. The tutorial was written by Marco Fioretti and, to be honest, it really wasn’t very good. It failed on three fronts.

  • The English wasn’t very good
  • The explanations of Perl were, in places, rather out of date or just plain wrong
  • The sample Perl code included some rather outdated practices

Let’s look at those three areas in more detail.

English Language

Obviously, English isn’t Marco’s first language. And his English is far better than my Italian. But I’d like to think that if I was writing for an Italian magazine, then the editors would tidy up my writing so that I didn’t make myself look too foolish. It appears to me that the Linux Format editors did nothing to correct Marco’s English. Here are a few examples of infelicities that slipped through.

“Before looking at the code, however, let me explain which data it uses…”
“Perl arrays and hashes are much more flexible than it shows in these pages…”
“The complete code of the procedures is in the DVD”

Of course, there’s nothing terrible there. We know what Marco meant. But the magazine would have looked a lot more professional if the editors had taken the time to edit this article.

Misunderstanding Perl

Marco’s knowledge of Perl seems a little mixed up or out of date in places. For example, he says:

You call a subroutine by adding a & to its name and passing parameters

It’s been several versions of Perl since the & has been required on a call to a subroutine. You won’t see it in any modern Perl code. It just makes the code look unnecessarily messy. Later on in the article, Marco says:

Perl does have while, if, for and unless, but it lacks a C-like switch operator for multiple, mutually exclusive choices.

The Switch module was added to Perl in version 5.8.0 (in July 2002). A much improved version called given/when was introduced in version 5.10.0 (in December 2007). Anyone who thinks that Perl doesn’t have a switch statement simply hasn’t been keeping up.

Outdated Perl

The Perl idioms that Marco uses are often somewhat outdated. In particular he uses the two-argument version of open instead of the safer three-argument version. He also uses global filehandles instead of lexical ones.

Marco also has a rather distinctive style for his Perl code, much of which runs counter to the advice in the perlstyle manual page or the Perl Best Practices book. In particular, his use of capital letters for variable and subroutine names will look very strange to someone used to reading Perl code formatted in a more traditional manner.

All in all, I think that Marco’s style does nothing to counter the reputation that Perl has for encouraging unreadable code and that with a little thought the same program could have been written in a far more readable manner.

Marco’s attitude to keeping up to date with Perl is nicely demonstrated by the books he recommends. “Programming Perl” and “The Perl Cookbook” were last updated in 2000 and 19982003. He would have been far better off recommending “Learning Perl” (which does keep up to date – the fifth edition was in 2008 and the sixth is currently in progress) or Modern Perl.

It’s a shame that the promised series of articles by Paul Fenwick hasn’t materialised. But it’s even more of a shame that Linux Format has fallen back to using articles written by someone who is not interested in keeping up to date with modern Perl. In light of this disappointment, I’d like to make the following offer to Linux Format.

If you want someone to write an article about Perl (whether that’s a one-off article about a particular topic or a series of tutorials), if you get in touch with me then I will find the best person to write that article for you. I may even do it myself if I have the time and the knowledge. Further to that, I am more than happy to proof-read and edit any Perl articles that you have currently in the pipeline.

I don’t believe that the Perl community in the UK is particularly difficult to track down. but if I’m wrong then I’m quite prepared to the the conduit that people to use to contact the community.

[I've found the sample program from the tutorial on the CD and have put it online.]

Marketing Perl

Sometimes people ask me why Perl marketing is so important. This morning I came across an excellent example of the kind of thing that we’re trying to counter.

In the current issue of Linux Format, there’s an article about building a Twitter client in the bash shell. It’s written by Nick Veitch – who seems to dislike Perl a bit. In the article he wants to URL encode a string and can’t find an easy way to do it in bash. He writes:

However, the compromise I’ve found for this isn’t too bad (props to http://stakface.com/nuggets). It uses Perl and, like everything in that language, it looks like you ought to sacrifice a goat or something before you run it.

perl -p -e 's/([^A-Za-z0-9.-~])/sprintf("%%%02X", ord($1))/seg'

It’s not clear to me which part of the Perl make him want to start sacrificing goats. Is it the s/// syntax that Perl borrowed from sed? Perhaps it’s the regular expression syntax that Perl shares with pretty much any language with regex support. Or maybe it’s the sprintf function that Perl borrowed from C and that many other languages (including bash) support with a pretty similar syntax.

Of course I’m not saying that Perl doesn’t have some grungy corners in its syntax. But the three pieces of syntax used in this code fragment look to me like things that should be understood easily by just about anyone with experience of programming in the Unix environment.

And if this code is so hard to understand, why use it? I don’t know what Nick’s programming language of choice is, but couldn’t you do exactly the same thing in Python, Ruby or PHP? I can’t believe that Perl is the only language that is so powerful. And I’d be very surprised if the same code didn’t look very similar in many other languages.

So why the unnecessary little dig at Perl?

Of course, it’s clear that Perl isn’t a language that Nick is particularly familiar with (neither, indeed, is the person who he took the solution from). Anyone who knew Perl would realise that Perl’s standard distribution includes the CGI module which contains an escape function which does exactly what Nick wanted – without exposing the programmer to all of that scary syntax. I would write Nick’s code something like this:

perl -MCGI=escape -e'print escape "@ARGV"'

There are a lot of people out there with really strange ideas about Perl. People who don’t bother to find out the best ways to do things in Perl. And having widely-read Linux magazines printing snide comments about Perl does no-one any good at all.

This is why I think that Perl marketing is important. We need to reach the people outside of the echo chamber and tell them that Perl isn’t the outdated, hard-to-use language that they are being told that it is.

Update: I should have pointed out that I’ve sent an abbreviated version of this to Linux Format. Hopefully it’ll be published in the next issue. And I’m considering proposing a series of articles on Perl to them.