Note to self

When your task is to go through the codebase of a large, ramshackle intranet portal consisting of multiple applications and plan the removal or replacement of all references to /Faculty of I(nformation )?T(echnology)?/ in user-visible text: don’t start out by removing the references from one .pm file and then commenting it as follows:

# removed Faculty of IT references

You’ll just end up annoying yourself later on.

Range regexps II

This post described the littlest little language I’ve ever implemented, which would expand ranges like ‘A-Z’ or ‘0-9′ in a string. Following some suggestions by BKB in the comments, here’s a bunch of stylistic alternatives.

My first one was kind of over-cautious. The range-expansion logic is separated out into its own function, which handles dumb stuff like invalid ranges, and also documents itself. Although ‘expand_range’ would be a better name for that.

    s/(.)-(.)/expand_pair($1, $2)/eg

BKB got it into one line. I wouldn’t do it like this, because on returning to this code, I’d have to spend too much time remembering what it was supposed to be doing:

    s/(.)-(.)/join('', map { chr($_) } ord($1)..ord($2))/eg

BKB’s first version was this, which he corrected:

    s/(.)-(.)/join('', $1..$2)/eg

I tried it, just to see what would happen, and found that the ‘..’ operator will not just return (1, 2, 3, 4, 5) from 1..5: it will also return (‘a’, ‘b’, ‘c’, ‘d’, ‘e’) from ‘a’..’b’ or (‘A’, ‘B’, ‘C’, ‘D’, ‘E’) from ‘A’..’Z’ In other words, it works for most useful cases.

In one way, I like this version the most: it’s a highly readable one-liner which works. In another way, I like it the least, because if you think about it for a little bit, it seems like it might be broken.

I then tried this, just to see what would happen:

    s/(.)-(.)/$1..$2/eg;

It turns every range into ‘1E0′, but I haven’t yet figured out why. Sometimes you just want to see how much tomfoolery Perl will put up with.