title | author | created |
---|---|---|
November 5 2010 — aim for the eye! |
Carl Mäsak |
2010-11-05 23:54:00 +0100 |
454 years ago today, the (second) Battle of Panipat was joined in northern India. The Wikipedia entry could use some editing, but here's the interesting strategic part of the battle:
Some nice things about this: (1) they were using elephants in battle, that's got to look impressive; (2) one of the combatants is named Akbar. But he's on the winning side, so it does not make much sense for him to yell "it's a trap!". Neither was he a admiral; he was an emperor.
❦
Instead of taking eight minutes to munch generate stuff for my blog, my static page generator now takes slightly above three minutes.
The change I made is adding in this subroutine, which returns True
if a given $target
file doesn't exist, or if it is older than its corresponding $source
file.
sub nonexistent-or-older($target, :than($source)!) {
return $target.IO !~~ :e
|| $target.IO.changed before $source.IO.changed;
}
I especially like the last line. I read it out loud as "or target IO changed before source IO changed", which is pretty much what the code is doing. I took a teeny bit of a liberty in using before
rather than <
, because it reads better. Generally I don't like that kind of catering to English-like code, but here it seemed too good to resist. Note that I kept ||
in favor of or
— even I have my limits.
Anyway, it turned out that the subroutine was generalized and lost its pretty perfectly-readable last line; some files like index.html
and feed.atom
are composed from several source files, and they all need to be checked against the target. So the final version I ended up with was this:
sub nonexistent-or-older($target, :than(@sources)!) {
return $target.IO !~~ :e
|| any map { $target.IO.changed before $_.IO.changed }, @sources;
}
[Addendum: sorear++ points out that I should be writing the above as $target.IO.changed before any(@sources).IO.changed
. Clearly that's what the above code wants to look like, platonically speaking. And we're back at extreme readability. I have much to learn still about the wonders of Perl 6.]
Much of the work that remains with psyde
is pushing calls such as this into a data structure so that whatever code the user produces, things like this will be called automatically. Right now I do it manually, and my psyde
script is ~200 lines long. When everything is stacked neatly into an API, I might get away with as little as ~40. Maybe less.