Skip navigation.

Harold's Home

   Home
  
XML version of this site

PHP Scripts

Index
CLI fun
Mail on 404
HB-NS (NewsScript)

Downloads

Applescripts
APOD to Desktop
Dreamweaver Extensions

Stuff

Writings
Other stuff
Central Grinder

OOOk Default:

VJ stuff
VJ Tools
Bananas
Strippers
Sample Movies

News

All articles in Perl

The Inspiration Particle
I was struck by an inspiration particle this morning.
These particles are extremely rare and hardly interact with normal matter, much like the much more common neutrino. Luckily while in the shower this morning one hit a neuron and I figured out how to read a whole file into a string (using Perl).

Most examples of file manipulation, in books and on the web, iterate through a file one line at a time, which is fine as far as it goes, but if your problem requires you to look at certain conditions in the entire file you're shit out of luck.

Here's how to read an entire file into a string:
open (DATA, "< $filename") or die "Can't read $filename";
my $whole_file = "";
while (<DATA>)
{
    $whole_file .= $_;# concatenate file into one string
}
close (DATA);


Now we can do all kinds of manipulations on the entire string, like using regular expression substitutions:
$whole_file =~ s/match pattern/replace pattern/g;.

Besides being quite elegant, in my case this actually speeded up my code by half a second. Instead of 0.6 seconds the script now only takes 0.1 second to run. As this script will run on about 50 files a month when deployed this means I just saved my employer 25 seconds computing time a month. I doubt I will get an additional christmas bonus though. My colleagues all shrugged when I came in this morning and tried to share my joy.
Still: Joy!

Here's how to time a script by the way (shamelessly ripped from the seminal Mastering Regular Expressions):
#!/usr/bin/perl -w
use Time::HiRes 'time';
my $start = time;

# your code goes here

my $delta = time - $start;
printf "$0 took %.5f secondsn", $delta;

Debugging switches in Perl
As I wrote earlier this week I've been busy with Perl. One of the things I wished to do whilst developing the script is printing debugging statements.

Ideally I'd like to use scriptname.pl together with -v, -vv and -vvv switches when calling the script to print various levels of debugging statements.

With the magic of the Getopt::Long module included in a standard Perl install this is not only entirely possible but also pretty easy.

Herewith some sample code:
#!/usr/bin/perl -w
use Getopt::Long;
my $v = "";
my $vv = "";
my $vvv = "";
GetOptions ('v' => $v, 'vv' => $vv, 'vvv' => $vvv);
if ($vvv eq 1)
{
    $v = 1;
    $vv = 1;
}
if ($vv eq 1)
{
    $v = 1;
}
if ($vvv eq 1)
{
    print "Debugging $0 level 1, 2 and 3\n";
}
elsif ($vv eq 1)
{
    print "Debugging $0 level 1 and 2\n";
}
elsif ($v eq 1)
{
    print "Debugging $0 level 1\n";
}

Save this script somewhere as samplescript.pl, make it executable (chmod 755 samplescript.pl) and call it using a various amount of v's.

Some more info on GetOpt::Long can be found at the A.P. Lawrence site.
This may be pretty basic stuff but I think it's pretty cool.

Just a small update: I have updated to samplecode to reflect the fact that multiple v's print more and more info.
For instance samplescript.pl -vv prints level 1 and 2 info, which could be very verbose, but doesn't include the most verbose feedback possible (which needs -vvv).

RFC822 formatted dates
I spend an insane amount of time today trying to get Perl to print an RFC822 formatted date (as used in RSS's <pubDate> element).

Here's a simple solution that worked for me, may it work for you too.

#!/usr/bin/perl -w
my $date = `date +"%a, %d %b %Y %T %z"`;
# RFC822 format: Thu, 25 Nov 2004 16:44:51 +0100
chomp($date);
print $date;

This uses the regular commandline program 'date' to construct the date. As 'date' adds a newline to that we chomp it off before printing it out to the RSS file (or the terminal in this case).

Net::SMTP
Today a colleague told me she was glad she didn't have my job. I find this strange as I was merely excited about Net::SMTP.

Yup, once again I'm struggling with Perl and seeing a script grow slowly (and expanding my horizons just a tiny bit more) is exciting stuff™.
The only thing I dislike about Perl is the fact that there doesn't appear to be an online manual like the manual for PHP. (Admittedly this is probably the bestest manual I've ever seen.) So if you have a tip on good resources* feel free to point them out either here in the comments or by email.
*) I already have the llama book but I forgot to take it with me today.

yahoo2mbox
Someone on the iCab mailinglist pointed me to a pretty nifty Perl commandline utility that will create an mbox file (this is the system used by Eudora and Apple's mail for example) from a Yahoo! group's mailinglist.

yahoo2mbox.pl on Freshmeat

You may need to supply a username and password to the script for certain members only archives.
Please note that Yahoo! limits the amount of data you can download in a certain time so the script will quickly flood the connection, leading to a temporary block by Yahoo!
To avoid this use the delay switch on the commandline: yahoo2mbox.pl -user=username -pass=password -verbose -delay=5 groupname.

Some notes:
- The test I did downloaded almost all messages perfectly (13 messages out of slightly less than 9300 were skipped for some reason).
- The file downloaded with Unix line-breaks. If you want to use the resulting file in something like Eudora change the line-endings to Macintosh format (or Windows if you're using that).
- The script needs some additional Perl modules that may not be installed on your system (like Getopt::Long and HTTP::Request::Common), install those either manually or using CPAN. I mentioned CPAN before.
- Don't forget to set the delay switch, you will be locked out for hours/ if not an entire day.

Creating text files containing the names of image files
Sometimes you get the oddest requests if you have a website feedbackform.
Here's one I received earlier.
> Hi! Just found your page through Google. I have a project that needs to be
> completed tomorrow. It involves creating 120 text files containing the
> names of 120 image files. I am of course desperately searching for an
> AppleScript that can do the job for me. Do you know where I could find
> one? To be more exact, what it needs to do is read the names of files in a
> given folder and for each one create a text file containing the name of
> the original file, and then save each file in the same folder. The files
> could have the same names as the originals but with a .txt suffix.
>
> Would greatly appreciate any help you could offer!


Now I have no idea why anyone would want to do something like this but the problem intrigued me so I wrote a small Perlscript that does what the guy wanted. I did the script in Perl as Applescript isn't really my forte and Perl is about ten times as fast (at least). That also gave me the benefit of reusing some old code. Code Reuse is Good™
I decided to put the textfiles in a new folder on the Desktop rather than in the imagedirectory itself, but that can easily be changed.
Another bonus of using Perl is of course that the script should run on just about any *NIX system out there with only minor modification. (It should even work on Windows systems running CygWin, though I haven't tested that yet and probably never will as my iBook has arrived, giving me the benefit of a completely portable OS X system even when at work.)
Anyway, the script (which is well-commented) is here if you want it: download the tar-gzipped script.

Show all items | Read all items | Show topics

About, copyright, privacy and accessibility | Mail