Mon, 13 Feb 2006

Return from a Block


This is probably obvious to a lot of people, but it's fairly rare that I learn a new Perl programming trick these days, and I don't recall ever having seen this one before, so I thought I would make a note of it here.

Now, some people will tell you that a function should only have one exit point. If you subscribe to that opinion then this trick probably isn't for you. Personally I find multiple exit points can frequently simplify logic and avoid the need for temporary status variables or conditional blocks. They can also be abused of course, but I don't consider that a reason to ban them outright. Maybe this attitude is why I get on so well with Perl.

Anyway, sometimes you have a block from which you would like multiple exit points. If this happens to be a loop you can use last to exit from it. But if it is not a loop you might not want to create a function just for this purpose. Well, the solution turns out to be trivial. Just use last in the block. It's even documented in perldoc -f last.

Note that a block by itself is semantically identical to a loop that
executes once.  Thus "last" can be used to effect an early exit out of such
a block.

I used this for the first time in my calandar and todo script. I'll probably use it again.

[/software/perl] permanent link

Blosxom Dates


Blosxom uses the inode modification time of a file to determine the date that should be used for that file. That's all well and good, but that information can easily be lost with a stray cp command for example, so I wondered about something a little more robust. I suspect it is very likely that someone has done something like this before, and it can probably be better done as a kwiki plugin, but I decided to add a line to each file telling what date should be used, and I wrote a tiny Perl script to set the modification time to that date. Then this script is called by cron every hour and I shouldn't have to worry about editing a file to correct a type, or to add an addendum, for example.

The system line in the script is a hack. I should probably use Perl's utime function, or at least check the return value or use system LIST, but sometimes you just want to get the job done.

So, for example, the start of this file is:

Blosxom Dates
meta-markup: date 200602131230
meta-markup: kwiki

The script I wrote is:

#!/usr/bin/perl

use warnings;
use strict;

use File::Find;

find(\&wanted, <~/g/blosxom>);

sub wanted
{
    return unless /\.txt$/;
    open my $f, "<", $_ or die "Can't open $_: $!";
    while (<$f>)
    {
        if (/^meta-markup: date (.+)/)
        {
            system "touch -m -t $1 $File::Find::name";
            last;
        }
    }
}

[/unix] permanent link




November 2022
Sun Mon Tue Wed Thu Fri Sat