Category: Perl

| 4 Comments

As you have probably already noticed, I recently implemented a random banner to be displayed on the main page of my website. By clicking refresh a few times you can see it working. Slowly but surely I will add more banners to my collection. It's an elegant way of enabling such a feature, so I thought that it'd be nice to share it with anyone interested.

Basically I create and then keep a bunch of 905x170 pictures which I save in the images directory. These can be randomly displayed in the banner div#homepage-image which is inserted using the /cgi-bin/rand-banner.pl random banner generator script.

This is made possible by including the following lines in the css file:

/* custom.css */
...
/* Banner is randomly generated */
#homepage-image { background-image: url('/cgi-bin/rand-banner.pl'); }
...

This script is run automatically every day by including the following line in the crontab:

@daily /www/kiffingish.com/cgi-bin/rand-banner.pl crontab

For those interested, I have also included the perl script which does all of the magic. It should be pretty straight-forward what this script does, which shows you the power of perl.

#!/usr/bin/perl

use strict;
use warnings;

# rand-banner.pl [crontab] :
# If called with 'crontab' just create the file list of banners,
# otherwise return the binary contents of a random banner immage
# for displaying on a web page.

use CGI;
my $cgi = new CGI;

# Directories based from root dir.
my $root_dir = "/path/to/root/dir";
my $cgi_dir = "$root_dir/cgi-bin";
my $doc_dir = "$root_dir/docs";
my $img_dir = "$doc_dir/images";
my $banners_lst = "banners.lst";

# Coversion file ext to http img/type.
my %ext2typ = ( bmp => 'bmp',
                gif => 'gif',
                jpeg => 'jpeg',
                jpg  => 'jpeg',
                png  => 'png',
                tif  => 'tiff',
                tiff => 'tiff',
);

# Only interested in the following file types.
my $img_filter = join(',', keys %ext2typ);

# If called with 'crontab' or banners.lst does not exist, collect
# list of banners from 905x170 files in images directory.
my $crontab = (defined($ARGV[0]) && ($ARGV[0] eq 'crontab'));
if ($crontab || (! -f $banners_lst)) {
    # See: http://www.imagemagick.org/script/identify.php
    my $output = `identify $img_dir/*.{$img_filter} 2>/dev/null |grep ' 905x170 ' | sed 's/\\[.*//' | sed 's/^.*\\///'`;
    open my $fh, ">", $banners_lst or die "Cannot open file '$banners_lst' for writing ($!)";
    print $fh $output;
    close $fh;
}

# All done if called from crontab.
exit if $crontab;

# Grab the latest banner list.
open my $fh, "<", $banners_lst or die "Cannot open file '$banners_lst' for reading ($!)";
my @banners = <$fh>;
close $fh;

# Take a random item from the list.
my $banner = $banners[rand @banners];
chomp($banner);

# Define banner image filepath.
$banner =~ /^.*\.(.*)$/;
my $ext = $1;
my $img = "$img_dir/$banner";

# Get the binary contents of the image file.
open (IMAGE, $img) or die "Cannot open image file '$img' for reading ($!)";
my $size = -s $img;
my $data;
read IMAGE, $data, $size;
close (IMAGE);

# Return image data to the caller. Be sure to disable caching so
# that each new request returns a new banner image.
print "Content-type: image/$ext2typ{$ext}\n";
print "Cache-Control: max-age=0, no-cache, no-store, must-revalidate\n";
print "Pragma: no-cache\n";
print "Expires: Wed, 11 Jan 1984 05:00:00 GMT\n";
print "\n";
print $data;

This might seem like alot of work for something very simple, but the challenge was worth it for me. I kind like this little added feature to my website. Have fun using it.

| 3 Comments

Since it's Sunday, I had a couple extra hours to spare in the evening, so I decided to play around some more with Moose.

More specifically I've seen MooseX::Declare mentioned on several occasions so why not give it a go myself.

This module provides a fancier declarative syntax you can use to define objects much more in the tradition of other so-called 'real' OOP languages. It also automatically includes MooseX::Method::Signatures, which means I can also use method declarations with type constraints to my heart's delight.

Also within the method declarations you get the good old $self as a freebie, meaning you don't always have to remember to use the my $self = shift statement. This makes the whole method declaration syntax cleaner and more elegant.

So having said all that here follows my simple example in which I'm able to try out some of the interesting deals on offer.

use MooseX::Declare;
use feature qw(say);

class Person {
    has 'age' => ( isa => 'Num', is => 'rw', default => 0 );
    has 'max_age' => ( isa => 'Num', is => 'rw', default => 75 );

    method get_older (Int $years_to_add = 1 where { $_ > 0 }) {
        $self->age( $self->age + $years_to_add ) if $self->is_alive;
    }

    method is_alive {
        return $self->age < $self->max_age;
    }

    method speak {
        say $self->is_alive ? "I'm alive!" : "I've kicked the bucket!";
    }
}

So let's see how good I've coded this, create a Moosified Person object and see if it all works.

my $x = Person->new( max_age => 35 );

while ($x->is_alive) {
    $x->get_older( 5 );
    $x->speak;
}

When I ran the program, it results in the following not so amazing output:

I'm alive!
I'm alive!
I'm alive!
I'm alive!
I'm alive!
I'm alive!
I've kicked the bucket!

I guess it works good, pretty darn good, will have to investigate this interesting functionality in more detail another day.

| 6 Comments

Whenever starting another Perl project, the very first command you should run better be the following:

$ module-starter --module=My::Module --author="[your-name]" \
    --email=[your-email] --builder=Module::Install

This provides the developer with a basic environment for writing solid Perl code, e.g. a new directory called My-Module with all the good stuff ready for use:

MANIFEST
README
ignore.txt
Makefile.PL
Changes
lib/My/Module.pm
t/pod-coverage.t
t/pod.t
t/00-load.t
t/boilerplate.t
t/manifest.t

After that it's the following, and off you go.

$ perl Makefile.PL
$ make
$ make test
$ make install

Life couldn't be easier could it?

| 4 Comments

These days it is not very often that a new and exciting Perl book comes along. That's why I was very excited when my Amazon.co.uk box arrived by post the other day.

I gleefully ripped the cardboard box open and held in my very own hands the recently released Effective Perl Programming, 2nd edition. Twice the thickness of the first edition and jam-packed with even more useful information.

This is a fantastic read which covers just about every aspect of Perl needed to program like the pros. Myself having had quite some experience with Perl was pleasantly surprised to learn new and interesting tidbits and other gems of information. Since having already read the book from cover to cover a couple times, I now keep it close at hand for reference purposes.

This wonderful book can be useful for beginners although it's pretty detailed and technical at times, but it's real use I believe is for experienced folks like myself who want to refresh their memories, extend their horizons, and recharge their enthusiasm for exploring new and possibly dangerous territories.

Here's an example of one of those one-liner gems, see if you can figure out what it does:

@a[ map { $_ * 2 + 1, $_ * 2 } 0 .. ( $#a / 2 ) ] = @a

From Chapter 2, Item 17 we find the following quote which appropriately summarizes one of the important philosophies: Perl is a "human" language in that it has a context-dependent syntax.

Finally, here are some other interesting places you might want to explore:

I can recommend you get the book also. Have fun.

| 3 Comments

I really like programming languages that allow you to think less without compromising the quality of your coding practices. Take for instance the new smart match operator '~~' which was introduced in the latest Perl releases.

if ( '123.0' ~~ 123 ) { ... } # String and number: TRUE

You don't have to keep trying to remember if a given scalar is a string or a number or 'numish' (both), sometimes wrongly using the standard operators ( eq, ne, lt, ==, >= ) in the wrong places causing bugs which are hard to track down.

Don't forget to enable this functionality by including the following in your code:

use 5.010;

Or you can enable the feature by calling Perl with the '-E' option at the command line.

Read this from beginning to end, and you then tell me with a straight face that it hasn't completely changed your life.

I believe it is high time that we stop dilly-dallying around, that we face the future for what it is, for what is was meant to be, and take the challenge.

for 0..3 -> $even, $odd {
    say "Even: $even \t Odd: $odd";
}

An appropriate theme song could be "Start of Something Beautiful" by Porcupine Tree (which just happened to be playing on Radioparadise twice while reading and then re-reading the link above on alternating even and odd days).

Going to attend the 7th Dutch Perl Workshop tomorrow in Arnhem.

Cannot wait to get up bright and early for a fun and relaxing day dedicated to the fascinating world of Perl. Last year was a blast and with lots of interesting talks I look forward to the trip.

During the ninety minute drive east, I'm going to crank up my latest Porcupine Tree CD and prepare myself for the busy day of mental gymnastics.

Sometimes after a long and weary day at work you just do not feel like making any comments.

@no_comments = grep {!/^#/} @blahblahblah; 

So this evening I happened to find out about autodie, thanks to the latest entry in the Modern Perl Books blog by chromatic. Cool stuff.

So I had to run home right away and try it myself, and it works! The following simple snippet:

#!/usr/bin/perl

use strict;
use warnings;

use autodie;
open (my $fh, "<", 'this-file-does-not-exist');
...

generates the following error message:

Can't open 'this-code-does-not-exist' for reading: 'No such file or directory' at x.pl line 8.

No need to waste all that time trying to remember where to stick all those die() statements all over the place (do I use || or do I use or?). So from now on I'll be using autodie just for fun and for work and for play.

Check out Modern::Perl for yourself.

| 1 Comment

All those weird Dutch characters were messing me up, and my Perl code was generating all kinds of cryptic errors, like: Malformed UTF-8 character, Wide character in print, etc.

You see, buried deep in the Perl innards somewhere, something was choking bad with such double dotted characters like ë, ö, etc.

I struggled with a number of my own home-grown solutions, but they didn't work well with all possible situations.

Finally in desperation, while perusing through one of my favorite recluses for inspiration, the good old CPAN, I happened to spy the Encode module.

A little bell rang in my head, and I knew I was in the right place. Getting warm, getting warmer, warmer, boiling, boiling hot ... bingo.

$text = Encode::decode('iso-8859-1', $text);

That's the simple and basic little statement that saved me and made my day. What could possibly be easier than that, and why was it so hard for me to find?

Maybe in the future I should visit CPAN more often and earlier, and not think so much of myself. As if I can always solve these grueling problems on my own.

I'm a pretty smart guy, but a little assistance from my Perl friends is always a welcome helping hand.

| 3 Comments

Being the hard-core developer type person that I am, every couple of years or so I like to take up a new programming language. This activity provides me with new insights into the wonderful world of programming, seeing how other people tackle interesting problems in different ways.

So last month I picked up a copy of Programming in Lua, and boy has it been a fascinating read. I can definitely recommend purchasing a copy of this book to add to your arsenal of programming literature.

Since my favorite programming language is Perl, each new book I study makes me rethink and compare things about other programming language with Perl (and its potential limitations). This is what I have been doing with Lua.

Two interesting features of Lua which would be great if Perl could do something similar are: "tail-call elimination" and "coroutines".

Tail-call elimination

Basically a tail-call is a goto in disguise. Place as the last statement in a function a return g(x) and you've got a tail-call:

function f(x) return g(x) end

Since the function f(x) has nothing else to do, it doesn't make sense having it wait around until the tail-call returns, using up unused resources like the stack. Might as well avoid using the extra stack space, making it possible to call an unlimited number of nested calls without worrying about the stack overflowing. The following example function can be called forever and the stack will never run out.

function foo(n)
    if n > 0 then return foo(n -1) end
end

A useful example application mentioned in the book, would be traversing a maze with the tail call providing a simple state machine describing going from one cell to the other. Each step goes north, south, east or west into the adjacent room, the exit being the tail-call which transports you from one room to the next.

Coroutines

A coroutine is another wonderful Lua concept. Very similar to threads, it provides a single line of execution within its own context. Several coroutines can work hand in hand, for example in a producer-consumer relationship. You can create, yield and resume coroutines.

Take the example of a producer coroutine reading lines from a file, passing the text to the consumer coroutine. The consumer coroutine receives from the producer.

function consumer (prod)
    while true do
        local x = receive(prod)
        io.write(x, "\n")
    end
end

The send and receive functions provide the gates on each side of the read-write pipe.

function receive (prod)
    local status, value = coroutine.resume(prod)
    return value
end

function send (x)
    coroutine.yield(x)
end

Finally, the producer-coroutine looks like this:

function producer ()
    return coroutine.create(function ()
        while true do
            local x = io.read()
            send(x)
        end
    end)
end

Coroutines can be used for many other things, like iterators or non-preemptive multi-threading applications.

What about Perl?

An interesting challenge could be to see how Perl might be used to implement similar functionalities like those that Lua does natively. As Perl advances and becomes more powerful, it makes sense to see how other programming languages work, and whether or not Perl could be extended to include more advanced concepts.

You'll also want to check out meta-tables and meta-methods, which I believe could be made part of Perl in the not-so distant future.

Official Website

If this all sound confusing, get the book where it's explained clearer and in more detail.

Be sure to check out The Official Lua Website where you will find alot of documentation and tons of examples to whet your curiosity.

| 11 Comments

During my lunch break I meandered my way along the canals and through the narrow alleys to the local book-store.

This book-store is pretty big, five floors filled with millions of books. They've got this huge eating area which always smells delicious. My favorite section of course is the computers section (followed by modern literature, and then science, and then psychology).

Several weeks ago, I was there and noticed that there were very few Perl books on the shelves. Only two measly copies of Mastering Regular Expressions and one copy of Learning Perl whose cover had an ugly crease in it.

With a rather disappointed look on my face, I asked the guy how come there were so few Perl books. He shook his head and told me that lately they just weren't that popular. The previous day he had re-ordered some titles, and they'd arrive in about a week or so.

Well there I was three weeks later, and there was not a single Perl book to be found. Just an empty spot becoming ever so cluttered with overflowing JavaScript and ActionScript books which were taking over the section dedicated to Scripts. What a sad day for me.

I believe it is high time to come out with some new titles. If I had more time on my hands maybe I'd try to write a book. There are many talented writers out there and perhaps they are coming up with some creative variations on the subject.

Hopefully with all of the new and exciting Perl-ish happenings on the rise, there will be a new barrage of literature appearing on the shelves some day in the not so distant future.

Until then I'll just have to be patient and scour the Internet looking for interesting tidbits in order to satiate my hunger.

| 1 Comment

The Perl module CGI::Carp allows you to define a different error handler than the boring "A Software Error Occurred" one by using set_message() like this:


use CGI::Carp qw(fatalsToBrowser set_message);
...
set_message(\&handle_error);

Now all calls to die() are caught and sent to the user-defined subroutine handle_error() which will present the user with a nicer HTML page rather than the boring default one generated by CGI::Carp. Pretty nifty.

The only problem with this is when you are debugging. The contents of the HTML page are barfed up and scattered across stdout. This makes it hard to search through all of the HTML and find exactly where the error description, error code and line number is.

So what you need to do is define a simpler user-defined error handler which generates a plain-vanilla printf message.

How can the script detect whether or not it is in the debugger? Simple, just check if &DB::DB is defined. If it is defined, then call set_message() and pass it the simpler error handler like this:


set_message(\&handle_error_printf) if (defined &DB::DB);
...
sub handle_error_printf {
    my $msg = shift;
    print("$msg\n");
}

You're on your way to a happy and productive life as a Perl debugger kind of person.

| 3 Comments

I've been doing alot of bash scripting the last few weeks. Struggling with all kinds of nasty problems and error handling stuff, I have discovered what a powerful utility this bash thing is.

Of course, when it comes to powerful scripting languages there's no substitute for Perl. Sometimes certain problems are a bit too complex for bash and it is nice to be able to fall back on Perl.

Let's say that I have an input file config.tmpl with a single line containing [% base_url %] and I want to generate a configuration file config replacing the value of base_url with $BASE_URL as defined earlier in the bash script, e.g. BASE_URL=http://www.kiffingish.com/utils.

One way of managing this is by using good old sed like this:


cat config.tmpl | sed 's!\[% base_url %\]!'$BASE_URL'!' >config

Sure this is fine and dandy, but what do you do if you have multiple lines in config.tmpl which need to be substituted on the fly? This is where Template Toolkit comes to the rescue.

I've added another line in config.in containing [% index_file %] which needs to be replaced with the value of $INDEX_FILE. A bash one-liner with the help of Template Toolkit works wonders:


perl -MTemplate -e '$t = Template->new(); $t->process('config.tmpl', {base_url => '$BASE_URL', index_file => '$INDEX_FILE'})' > config

If you are bit paranoid, you can extend the above one-liner with some error checking just in case:


perl -MTemplate -e '$t = Template->new() || die "$Template::ERROR\n"; $t->process('config.tmpl',{base_url => '$BASE_URL', index_file => '$INDEX_FILE'}) || die $t->error()' >config

Now if you are like me and even more overcautious. one more sanity check is in order. Always expect the worst, and if this worst happens, make sure that you can trouble-shoot the situation quickly and efficiently.

That's why at the beginning of the bash script, I also double-check that the Template Toolkit module is indeed installed.


# Make sure that the Template Toolkit is installed
perl -MTemplate -e1 &>/dev/null
if [ $? -ne 0 ]
then
    echo Template Toolkit is not installed, please install first.
    exit $?
fi

Isn't the Template Toolkit truly magical? That's why I use it very often to help automate even the most complex chores. Thanks alot Andy.

I'm not about to claim that I'm some kind of expert on the subject, but I think it's fair to say that I've experienced my fair share of ups and downs over the years which makes me a little bit wiser.

Put simply the questions is how do we avoid failure when designing and implementing complex software products?

This is how I would answer that question.

  • The golden rule of thumb to avoid failure is to figure out early what the biggest risks to success are, and then to keep them in mind every single day. Keep this up until success is achieved.
  • Another key to avoiding failure is to admit openly when things start to go wrong, or better yet when you expect that things might go wrong. Don't hide the truth because you are worried that your boss will get angry or that you will lose face with your team members.
  • If things start to go better than expected, then celebrate it and make it publicly known. You guys have struggled really hard and deserve the recognition for work done well. Go out and have a party, but don't get too drunk because it's bright and early as usual the following day.
  • Feel proud of what you are making and treat it like your baby. Protect and cherish it, nurture it and play with it.
  • Admit defeat if needed and just start all over again. It is much better to restart with new insights than it is to plug along with an ugly product which keeps getting uglier, and finally slowly sink into quicksand.
  • Use sound metrics to measure progress and regularly decide where you, where you are headed, and possible obstacles along the way which will delay progress.
  • Learn from your mistakes, write them down, keep this list with you at all times, and reread it at least twice a day.
  • Finally remain open-minded, honest and embrace change, which will happen whether or not you want it to. Change hurts while it is happening, but afterwards it makes you feel a whole lot better.

One could easily say that the statements above apply to developing successful software products as well as to most challenges in life.

There's been some talk lately about this new-fangled Apache module called mod_perlite a.k.a. the do-it-all like mod_php but better module for Perl.

Since by nature I am a curious kind of guy looking for yet another interesting challenge, I'm going to have a look at it for myself.

The idea behind mod_perlite is appealing. As a lightweight replacement for mod_perl, mod_perlite is much easier to install, embeds a Perl interpreter in high memory, supports the core CGI functions and has a much smaller memory footprint.

Good old mod_perl is very powerful indeed. I've done alot with it and think it's a fantastic beast. However, it is simply not accessible to the average bloke because it is complex and hard to learn. Have you ever realized how heavy the book Practical mod_perl is with its nearly one thousand pages?! Also, hosting companies are not eager to allow its subscribers to twiddle around with potential dynamite and having to support poor customers sucked down in mod_perl quicksand.

Hey, let's make Perl as easy as PHP for regular users to deploy and for web hosting companies to give as an appealing dynamic web application server stack!

For those masses of kind folks out there who are not computer savvy and not waiting for the headaches of fighting mod_perl, this makes mod_perlite a no-hassle and feasible solution for the low-end plain vanilla servers out there.

Imagine how screaming fast it could be on quad servers hooked up together to provide high performance dependable web solutions.

Perhaps even Lighttpd can come into the picture, why not? Hey now, that's an interesting idea. Writing Lighttpd modules is fairly effortless and hooking this up with Lua could become a real eye-opener.

Wouldn't it be nice to have an one-two-three web server setup that installs easily and just does what it is supposed to do? The blog server market is exploding and could very well benefit from this.

I've got some time on my hands for the next week so I'm going to check mod_perlite out for myself.

Came home today to discover a package from Amazon waiting for me on my desk, and when I opened it I was excited to discover that the new Catalyst Book arrived.

I already started reading it, and I plan to devour it fully this weekend between my two golf tournaments.

In the meantime, I've already learned alot about the Catalyst Web Framework through weeks of hands-on experience at work, but I'm sure there's alot more extra stuff to learn by reading this fine book.

I'll be sure and write a (positive) review when I'm done.

There were many interesting presentations given at the Sixth Dutch Perl Workshop earlier this year in Arnhem. The event was well organized and many people showed up.

I met many really interesting people there and even had the honor of giving my own presentation in front of the dynamic and fun-loving public. My presentation was called Perl and Scrum. Here's the powerpoint.

In the evening they drank some whiskey and played this weird card game called Fluxx.

| 4 Comments

For years now, I've been using a really great blogging tool called Movable Type Pro. This advanced utility does pretty much everything you'd ever want. Well, most everything that is.

Wouldn't it be great if you could also somehow automatically send out a twitter update (tweet) every time that you've created a new blog entry? Something like this:

Well, as of this very moment you can! All you have to do is keep reading, and if you are patient enough and read carefully what I have to say, then I will reveal to how it's done. Actually it's really quite easy.

Let's call it "blog tweeting".

This is the approach. Whenever a new entry is created, we want to tweet something interesting to the big bad world, grab everyone's attention that something really important has happened. Some kind of catchy phrase would be nice. I use the text "Yet another blog entry" followed by the entry title followed by a url you can click on if interested.

Nowadays, since tweets are deemed short and to the point, rather than use the complete url, which can get quite long, we want to include a shortened version of the url which fits nicely into the short message. The tinyurl service is the popular choice nowadays, so I will use that.

First of all, you need to have a couple CPAN modules installed, namely Net::Twitter and WWW::Shorten::TinyURL. These are installed in the usual way:

$ sudo cpan -i Net::Twitter WWW::Shorten::TinyURL

Net::Twitter is based on Moose meaning that the installation will pull in tons of extra dependencies. If you do not want this and only need to tweet an update, then you probably only want to install the lite version:

$ sudo cpan -i Net::Twitter::Lite

Alright, let's get started. At the top of your Perl script blog-tweet.pl include the following CPAN modules:

use DBI;
use WWW::Shorten::TinyURL;
use Net::Twitter::Lite;

Now you want to setup the usual database stuff using your movable type username and password like this:

my $dsn = 'DBI:mysql:<database>:<hostname>';
my $db_user_name = '<user_name>';
my $db_password = '<passwd>';
my $dbh = DBI->connect($dsn, $db_user_name, $db_password);
my $url = 'http://www.<domain_name>.com/';

The database query needs to grab the latest blog record from the mt_entry database where it is a blog entry (entry_class = 'entry') and the entry is published for view (entry_status = 2). This is what it should look like:

my $sth = $dbh->prepare(qq{
    select
        entry_title as 'title',
        entry_basename as 'basename',
        entry_created_on as 'created_on'
    from
        mt_entry 
    where
        entry_status = 2
            and
        entry_class = 'entry'
    order by
        entry_created_on desc
    limit 1
});
$sth->execute();
my $rec = $sth->fetchrow_hashref();

The field formats are:

  • created_on - "yyyy-mm-dd hh:mm:ss"
  • basename - "word_word_word"
  • permalink - "blog_root/yyyy/mm/word-word-word.html"
my $basename = $rec->{basename};
$basename =~ s/_/-/g;
my ($year, $month) =
    $rec->{created_on} =~ /(\d\d\d\d)-(\d\d)-.*/;
my $title = $rec->{title};
$url .= "$year/$month/$basename.html";
my $prev_url = '';

Get the previous url, if possible.

if (open(FH, '<blog-tweet.txt')) {
    # File exists.
    $prev_url = <FH>;
    close FH;
}

If new blog entry created, tweet update.

if ($prev_url ne $url) {
    open(FH, '>tweet-my-blog.txt')
        or die "Can't open 'blog-tweet.txt' file: $!";
    print FH $url;
    close FH;

    my $nt = Net::Twitter::Lite->new(
        username => '<username>',
        password => '<passwd>');

    # Convert longurl to shorter tinyurl.
    my $short_url = makeashorterlink($url);
    my $tweet_message =
        "Yet another blog entry '$title' $short_url";

    # Tweet you Update!
    my $result = eval{ $nt->update($tweet_message) };
    
    if ($@) {
        print "Tweet update: $tweet_message, failed ($@)\n";
    }
    else {
        print "Tweet update: $tweet_message, succeeded\n";
    }
}
else {
    print "No new blog entries yet.\n";
}

Finally, don't forget to cleanup.

$sth->finish();
$dbh->disconnect();

The final step is to create a simple cronjob which will run this script every once in awhile. Since I usually write at most one or two entries a day, I've added a cronjob to run once a day at 16.30 in the afternoon:

# crontab -e
30 16 * * * cd /path/to/cgi/scripts && ./blog-tweet.pl

That's pretty much it, have fun blog tweeting!

| 5 Comments

Everywhere you look these days in Perl literature, chances are that you'll come across references to Moose, how great and flexible it is and so forth.

Since I had such a lousy game of golf this afternoon and lost my first matchplay round six down, I needed a way to inspire myself. So what could be better then reading the Moose::Manual this evening?

Boy, was I in for a frustrating surprise.

I hate to admit it, but all this Moose stuff is not easy for me (grumble). Rather than getting all excited and inspired like I hoped, I'm sorry to admit that it's making me feel rather sad that I cannot figure this out.

Am I supposed to be able to understand this Moose stuff? After so many years of getting pleasure in tackling all kinds of complex programming issues, have I simply reached my limit? Time to give up trying to be a Perl guru, jump ship, and be forced to become a golf hacker the rest of my life? What do other fine Perl souls out there think about it?

Here's an example that better illustrates my frustrations. In the Moose::Manual::Concepts one goes on and on about classes, attributes, methods and roles. Not bad. A role has zero or more of this, a role has zero or more of that, a role has zero or more of this and that. Getting more difficult.

Later on one learns that a role is somewhat like mixins or interfaces in other OO languages. Getting more difficult. What the heck is a mixin (and how do you pronounce it)? The good old Wikipedia saves the day with a nice, clear definition:

"In object-oriented programming languages, a mixin is a class that provides a certain functionality to be inherited by a subclass, while not meant for instantiation (the generating of objects of that class). Inheriting from a mixin is not a form of specialization but is rather a means of collecting functionality. A class may inherit most or all of its functionality from one or more mixins through multiple inheritance."

Huh? Nearing apogee and getting impossibly difficult.

Whatever happens, I have promised myself to hang in there. Read and reread as much as I can. Stay smart. Get smarter. Figure it all out or else.

What with so many Perl gurus out there getting all fired up about Moose, mixin and stuff, why I want to join the fun as well!

Tomorrow it's all about Moose::Manual::Classes and then next the world.

Wish me luck.

| 3 Comments

Or perhaps better yet I should rephrase the title above and instead write: Is agile development conducive to Perl?

For the last ten years or so there's been a big rage about the benefits of agile software development and how much better this methodology is compared to good old Waterfall or RUP or Ruby on Rails or whatever.

I would like to claim that Perl is just as good if not better than any other programming language when it comes to going agile. I've used it often enough and it has resulted in successful products hitting deadlines and bringing in big bucks. Who ever told us that early-to-market is an impossible task?

Perhaps Perl is not ideal, but it's flexible enough. Perl fosters creativity in such a way as to bring about visible results very quickly. There are many ways of doing things, and these alternative can be compared, the good with the not so good and even the bad with the outright bad, when choosing the most viable direction to take. Perl means moving forward not backwards.

Is speed the most important? Sure. Should we keep quality in mind? Yes, of course. Is there enough time to test? You better or else. Should we demo even though it's not quite ready. Yes and yes.

Let's have a look at Scrum which is one way of being agile. Since I've had more experience there, I feel more comfortable discussing it in light of the Perl programming language.

Scrum's success is based on a number of important concepts including the following:

  • Describe requirements as user stories
  • Prioritize tasks by business value
  • Commit to short-term goals and go for it
  • Allow the team to do anything to accomplish the goal
  • Do not disturb development during each cycle
  • Develop quickly and pragmatically

  • Take part in daily stand-up meetings
  • Measure speed by iterative development cycles
  • Empower the development team to make any and all decisions
  • Embrace change because it will happen
  • Review and improve
  • Foster bleeding-edge technology that might break things
  • Accept delays as part of life and make them public
  • Tackle risks early and do not fear failure
  • Verify, rework and move forward
  • Be proud of what you create
  • Have a fun and relaxing time getting things done

I could go on and on explaining the fine art of doing Scrum within the wonderful world of Perl, but I believe I've said enough for the time being.

Hopefully my short discussion here has tickled enough people out there to make them think and reflect upon their own experiences. Enough so at least that they are inspired to leave comments of all kinds, foster even more discussion, defending and/or judging good old Perl as a agile way of doing things (or not).

So is Perl really conducive to agile development? I think so.

| 4 Comments

Recently I've been setting up an extensive test harness suite for a web-based application running on the Catalyst Web Framework for Perl.

In addition to the popular Test::MoreCPAN module, many of the tests make use of the CPAN module Test::WWW::Mechanize::Catalyst where I run automated scripts to access various pages, fill in fields with various values, submit forms and check for success or failure.

One of the tests involves creating a new user account that generates a notification email which is sent to the new user. Within the message text there is a verification link. The idea is that upon receiving this email, the user will click on this link and be redirected back to the application to a welcome page. This welcome page verifies that registration has been completed successfully. The user is invited to login in by submitting a form with the username and password pre-filled.

The problem is that I do not want to be generating all kinds of external emails into the big bad world for these tests. Besides, how can I use automated scripts when they depend on external events like users having to click on links in emails wherever they might be?

So here's the trick. First of all I redefine the Email::Send::send() method so that I can hook into it thereby mocking it's behavior. This redefined method is used to scrape out the embedded validation link we must click on in order to finish the registration process.

our $email_mime_ref;
{
    no warnings qw/once redefine/;
    *Email::Send::send = sub {
        my ($self, $message, @args) = @_;
        $main::email_mime_ref = $message; return 1; };
}

Note that we use no warnings qw/once redefine/ in order to disable the warning messages for redefining the method and only using it once.

Whenever Email::Send::send() is called, we copy the message for later use. Note that since we are in the namespace of Email::Send when this is called, we need to make sure that the message is copied back into the namespace of where we are calling from, namely $main::*:

$main::email_mime_ref = $message;

Later on in the test suite it is time to submit the form like this:

$mech->submit_form(
    form_number => 0,
    fields => $fields,
    button => 'submit' );

Now scan through the message text and extract the uri, there should only be one present. I'm using the CPAN module URI::Find to simplify life.

my @uris;
my $finder = URI::Find->new( sub { push @uris, shift; } );
$finder->find(\$email_mime_ref->body_raw);

As a sanity check (you never know) I check that indeed only one link is present in the message text:

is(@uris, 1, "Found only one URI '$uris[0]' in email message");

Finally, we simulate clicking on this link which should bring us back to the welcome page:

$mech->get_ok($uris[0], "Click on URI '$uris[0]'");
$mech->content_contains("Welcome " . lc($username) . 
    ", your email has been validated. Please log in.");

We did it, so let's pat ourselves on the shoulders and call it a night.

Here's a review I wrote about the book 'Perl Testing: A Developer's Notebook' by Ian Langworth & chromatic.

"Excellent overview and introduction to the art of testing Perl programs. This modestly-sized book covers a wide range of types of testing from the very simple Perl script to the more advanced web application. It's not only about writing tests but managing them as well and then making sure that your code can be distributed in a useful manner. I especially found the chapter about testing untestable code very insightful, where the use of mocking modules and mocking objects is essential. Have you ever needed to override live code by hacking deeply into their packages? Well, this book will help you out with this delicate matter and make you more confident with testing, testing and testing. Most people have an aversion to testing, but here you can get quickly up to speed and even enjoy the fine are of testing. There are many references to other CPAN modules which is useful to know about. Of course, any book authored by chromatic has to be worth the read."

O'Reilly books
| 2 Comments

Ever wondered how to quickly convert an array to a hash on the fly? Well here's one way to do it:

my %h = map { $_ => 1 } qw/one two three four/;

Feel free to come up with other perhaps more efficient and/or elegant and/or cryptic ways of doing this.

Thought I was being real clever by trying the following last act of pure desperation:

$SIG{__DIE__} = sub { print "Please don't let me die!\n"; };

Unfortunately those were my last gasping words before I was aborted and sent to who knows where.

Screenshot-Padre 0.35.png

Padre - Perl Application Development and Refactoring Environment

Special thanks goes to Gabor Szabo for helping me out.

If like me you use Ubuntu, don't forget to read the download instructions very carefully and do the following:

$ apt-get install libwxgtk2.8-0 libwxgtk2.8-dev libwxbase2.8-dev libwxbase2.8-0 
$ apt-get install libmodule-build-perl libextutils-cbuilder-perl libmodule-pluggable-perl g++

Optionally, which was the case for me, you might also have to run:

$ sudo cpan -i Wx Alien::wxWidgets Padre

Then sit back, fire it up and enjoy:

$ padre
| 3 Comments

After hearing the good news Padre 0.34 released I've been giving it a go but with little success.

Despite claims on the download page, I've been struggling now for two whole evenings with very little luck.

$ sudo cpan -i Padre

Looks pretty innocent and straight forward doesn't it? Yeah right. A bit of a nightmare, which is really too bad. I was really excited to try it out and get involved myself.

You might also like to read Padre + Catalyst. See also Padre, the Perl IDE.

| 6 Comments

Let's say that you need to check the validity of some input value. If it is found in a list of acceptable values then you continue otherwise you need to croak some error message.

For starters let's assume that the list of acceptable values is contained in the following array:

my @list = qw(email name telephone address);

Also don't forget that in order to be able to croak you need to include use Carp; in the file.

Here's the most straight forward way to do it:

sub func
{
    my $value = shift;
    my $found = 0;
    for my $next (@list)
    {
        if ($next eq $value)
        {
            $found++;
            last;
        }
    }
    croak "Invalid value '$value'" unless $found;
    ...
}

Here's another especially clever albeit slightly cryptic way to do it[1]:

sub func
{
    my $value = shift;
    { map { $_ => 1 } @list }->{$value}
        or croak "Invalid value '$value'";
    ...
}

Finally, if you are familiar with the List::MoreUtils module, then here's yet another way to do it:

use List::MoreUtils qw/any/;

sub func
{
    my $value = shift;
    croak "Invalid value '$value'";
        unless any { $value eq  $_ } @list
    ...
}

As you can see there are many correct ways to do it and probably many more.

[1] Perl Medic p. 122

| 2 Comments
About ten days ago, I ordered the book 'Perl Debugged' and I was pretty excited when the package arrived today, falling gently from the mail slot in the door and landing upside sown on the hallway mat.

At first I was a little surprised how thin it seemed, but still full of anticipation, I ripped the package open and yanked out the book.

It turned out to be a copy of 'Mijne erste Trompetenshule' some German music book for kids learning how to play the trumpet.

When you think about more closely, it makes sense that Perl and trumpet playing have alot more in common that you realize.

What a letdown, but kind of funny and ironic at the same time.
| 1 Comment

Here's an easy one-liner which will automatically update all of the CPAN modules installed on your machine:

$ sudo perl -MCPAN -e 'CPAN::Shell->notest(install => CPAN::Shell->r)'

I always do it with sudo but you might not have to depending on your preferences.

Since waiting around for all of the tests to complete can be quite dull, I use notest() which might be considered risky by others.

Random entries

Here are some random entries that you might be interested in:

Recent Assets

  • 2023-09-24-jong-tegen-oud-1.jpg
  • 2023-09-24-jong-tegen-oud-2.jpg
  • just-call-me-fred.png
  • foggy-morning.png
  • oma-2023-07-27.jpg
  • i-almost-died.png
  • chipping-from-twenty-meters.png
  • de-koepel.png
  • screenshot-www.udemy.com-2023.05.18-10_02_39.png
  • screenshot-www.golf.nl-2023.05.08-09_57_30.png
  • IMG-20230423-WA0000.jpg
  • me-and-my-radio-paradise-hat.png

Recent Comments

  • Long time no see: I remember them, as well. I remember Donald was my ...
    - Charles
  • Bridge to the moon: Yes it was a drawing and my older brother told me ...
    - jpmcfarlane
  • Bridge to the moon: Wow, that's quite a coincidence that we both sent ...
    - Kiffin
  • Bridge to the moon: Hello I was in my teens when Gemini 4 went up that ...
    - jpmcfarlane
  • Back to work: Congratulations Kiffin, I hope it is something you ...
    - KathleenC

Golf Handicap

Information

This personal weblog was started way back on July 21, 2001 which means that it is 7-21-2001 old.

So far this blog contains no less than 2498 entries and as many as 1877 comments.

Important events

Graduated from Stanford 6-5-1979 ago.

Kiffin Rockwell was shot down and killed 9-23-1916 ago.

Believe it or not but I am 10-11-1957 young.

First met Thea in Balestrand, Norway 6-14-1980 ago.

Began well-balanced and healthy life style 1-8-2013 ago.

My father passed away 10-20-2000 ago.

My mother passed away 3-27-2018 ago.

Started Gishtech 04-25-2016 ago.