April 2013 Archives

SEO Tips for Perl Advocacy

| 1 Comment

A few moments after I posted Perl Web Pages and Search Engines, someone at Big Blue Marble said "You should explain what you've done technically."

I run a few sites, including this one. I've worked on the technology behind a few others. We've been working on a short article called SEO Tips (in Ten Minutes) to explain a few easy techniques to help web crawlers find out exactly what a web page is about and to display it to the people who could most benefit from it.

It's still a work in progress at the moment, but I've used it those techniques on several BBM projects so far, including Trendshare and its investment guide for novice investors, as well as ModernPerl.net, and even the nascent family recipe site Blender Recipe Reviews.

I know Propaganda.pm tracks the performance of Perl advocacy campaigns now. If you have a blog or website or articles about the Perl programming language, maybe some of these tips will help you get more and better traffic, help crowd old tutorials and outdated out of the top search results, and improve the visibility of our favorite programming language.

Imagine, for example, if every one of the generated pages of search.cpan.org had the phrase "the Perl programming language" in it and relevant meta description tags....

Perl Web Pages and Search Engines

| 2 Comments

While browsing Perl 7, the story of, I noticed that Perl6.org has a HTML <meta name="description" /> tag. I also noticed that it claimed that "Perl 6 is the next major version of Perl".

(Don't worry; I fixed that.)

I spent a lot of time in the past year working with family members on websites. Part of that work required me to learn a lot more about SEO and usability. (Thank goodness for schema.org, for example.)

The meta description is highly useful. It allows a search engine to display a contextually accurate and complete (short) phrase when the engine lists the page in a result set, rather than a snippet of semi-highlighted keywords taken out of context. This, of course, can make the result list much more useful for readers.

(I've spent a lot of time adding this description to the pages here on this site. I haven't finished. I've noticed it's improved search engine traffic here and elsewhere though; it's worth it.)

When the inevitable discussion of "How can the active Perl community make itself and all of its great work more visible to the rest of the Internet?" comes back in the next two or three months, keep in mind the idea of robustness: having useful information is important, but presenting that information in a way that's easy for machines to interpret is just as important.

(I hope that Propaganda.pm is listening. I'm glad to see that perl.org is too.)

The Fat Comma and Clarity

One of the simplest but most useful examples of TIMTOWTDI in the design of Perl is the fat comma operator (=>), which acts like a regular comma except that it automatically quotes barewords used as its left operands. It also looks like an arrow, so it leads from left to right and implies a stronger association between its operands than the normal comma does.

You can see this in hash initializers:

my %dogs = (
    alpha => 'Rodney',
    clown => 'Lucky',
    puppy => 'Rosie',
);

... which makes the association of key with value clearer than the standard comma does:

my %dogs = (
    'alpha', 'Rodney',
    'clown', 'Lucky',
    'puppy', 'Rosie',
);

... and much clearer than even an idomatic bare list initializer might:

my %dogs = qw( alpha Rodney clown Lucky puppy Rosie );

You can use the fat comma in place of the normal comma almost anywhere its autoquoting semantics don't change your code. (I can't think of any at the moment, but there might be a JAPH somewhere that proves me wrong in a strange and wonderful away.) With Moose and other semi-keyword libraries using lots of named parameters, you often see code like:

has 'name' => (
    is => 'rw',
    isa => 'Str'
);

has 'age' => (
    is => 'rw',
    isa => 'Int'
);

There's nothing wrong with that code, but I confess that it confuses me a little bit every time I skim it. I understand the desire to emphasize the name of the attribute (name and age) and to suggest that all of the other parameters provided to has are merely refinements of the behavior of the attribute, such that grouping them by the parentheses makes them into a single visual unit associated with the attribute's name, but I never quite seem to read it that way.

(The lack of autoquoting in this example bothers me too.)

I started to think about this when I read some production code I'd written:

return $self->collaborative_collection( Name => $identifier );

The arguments to collaborative_collection() are the name of the collection and a unique identifier for the collaborative making the request. There's no logical connection between the name and the identifier. I only used the fat arrow for its autoquoting behavior.

The API call looked as if I were passing a single keyword argument, which isn't the case at all. I was passing two distinct arguments.

The temptation to use less punctuation (removing quotes) by using a little more punctuation (a fatter comma) had let me write code that would mislead other readers. If Perl had a different syntax for keyword arguments, I wouldn't have had this problem, but that's not going to fix this code here and now.

After some reflection, I decided that the association that the visual appearance of the fat comma implies is important enough to the reading of code that we should only use it where that relationship is present in the semantics of the code. Sure, it's a little extra punctuation that we don't have to type, but it's clearer code when we read it, and that's more important after all.

How to Identify Clunky Perl 5 Code

In an old discussion on publishing bad examples of Perl 5 code, I left the other side of the issue unaddressed. If people who publish Perl code examples have a responsibility to publish good code (or at least to avoid publishing bad code), how do they discern between good and bad code? How do interested novices distinguish between good and bad examples?

The latter question has a flippant answer. If they could do so reliably, they would no longer be novices and would no longer have to worry about the question.

We can give them some hints, though.

Compiler Support

One of the reasons behind creating a CPAN distribution called Modern::Perl is to help distinguish between Perl 5 code written for the pre-2000 era and Perl 5 code written to take advantage of current features and best practices. Though neither the presence of use Modern::Perl: is a guarantee that the remaining code is sufficiently good nor the absence of that line is evidence that the remaining code is insufficiently modern, you can say that most good examples of Perl 5 code circa 2013 do include:

use strict;
use warnings;

...or:

use Modern::Perl;

...or:

use 5.014;
use warnings;
k

...or:

use Moose;

... or:

use common::sense;

... or something similar.

Without that safety net, it's easy to make inadvertent mistakes that perl5 would otherwise happily warn you about. You can write great code without them, but most of the great Perl programmers I know prefer to work with that safety net. I make enough typos myself that strict saves me debugging time multiple times every week.

Perl as Perl

Perl's origins lie in system administration as a tool more flexible and powerful and wieldy than shell but also easier to use and manipulate than C. Perl is also available as part of the default system installation on many, many operating systems, and well-written Perl programs tend to be more portable than shell programs, as the Unix fragmentation wars manifested themselves in frequent skirmishes around shell and system utility syntax and features.

Consequently, a lot of Perl code in the wild is slightly more portable and slightly more featureful than shell scripting. That's a charitable way of saying that it reads like a shell script: bare-bones procedural code that calls lots of system programs and doesn't worry much about structure, just getting a job done quickly by gluing together a lot of other little programs.

That's all well and good in the sense that you can write good Perl code for those tasks, but there's a tendency to use Perl as merely Bourne shell with a better syntax, neglecting all of the language constructs and core library features to write maintainable, clear, effecient, effective, powerful, and useful programs.

This rule is necessarily fuzzy; I have a lot of useful, powerful, maintainable programs that perform system() calls or use qx// for very good reasons...

... but code sprinkled with calls to `ls` and `date` and `sort` and `grep` without at least a comment explaining why avoiding Perl's builtins in favor of external utilities is necessary should trigger red flags in your mind.

The same goes for long listings of code without functions (or even obvious whitespace breaks between code paragraphs).

You can use Perl 5 as an improved shell, but you lose out on a lot of power of Perl.

Inelegant Code

Code doesn't evolve. Code either gets designed or code accretes. You can tell when code doesn't have a design ethos because it's all over the place. Even a simple system administration program of more than a couple of dozen lines can be more maintainable when it has sensible variable names and, yes, distinct functions.

I've seen monolithic CGI programs (it's always CGI programs, isn't it?) which use complicated nested conditionals to twist and turn and gyrate to display multiple distinct views.

I've seen the most awkward code written by people who couldn't make enough sense of what they wrote to distill a problem down into less than a few hundred lines of code.

(Some of the strangest code I've ever seen came from the keyboard of a person who goes to great lengths to pass code to import methods for delayed execution because, and I'm paraphrasing pretty closely here, "Why should I have to put different classes in different files?" I'm all for self expression, but the result is an undebuggable mess that doesn't look like any Perl code I've ever seen anywhere else.)

I know it's a lot to ask of novice programmers, but when you find yourself wrestling with code and feeling like you're having to do things the hard way, step back for a moment. You're probably not solving a problem no one has ever solved before. You're probably solving a problem many of us have solved a hundred times before. There's probably an elegant way of getting from there to here.

If you're making a mess, stop. Take a deep breath. Then solve a small piece of the problem in an elegant way. Make sure you understand it. Then solve another small piece. Make both pieces work together elegantly. Make sure you understand that. Repeat until you've solved the problem.

I know elegance is a subjective measurement, but I can tell you about its absence. Inelegance is often the result of mockingbird copy and regurgitate programming, where you're scrabbling around with something that'll probably work if you can put the symbols in the right order. Also, it's midnight and you're wearing a blindfold and you're underwater in a cave.

Then again, a map statement looks inscrutable to someone who doesn't know that it's a little bit like a loop that you don't have to write yourself and an object looks inscrutable to someone who doesn't know that it's a way to draw fences around information and behavior and an aggregate data structure looks inscrutable to someone who doesn't yet understand that names exist solely for the humans and that doing a thing once isn't nearly as nice as doing it innumerable times to things that don't have names.

... but the principle remains. You might not be able to say why certain code is messy and you might not currently have the skills to clean up the mess completely, but if you can cultivate the ability to discern elegance in code, you can at least know which example code to avoid.

Modern Perl: The Book

cover image for Modern Perl: the book

The best Perl Programmers read Modern Perl: The Book.

affiliated with ModernPerl.net

Categories

Pages

About this Archive

This page is an archive of entries from April 2013 listed from newest to oldest.

March 2013 is the previous archive.

May 2013 is the next archive.

Find recent content on the main index or look in the archives to find all content.


Sponsored by Blender Recipe Reviews and the Trendshare how to invest guide

Powered by the Perl programming language

what is programming?