I missed an easy solution to a silly problem
A few years back I wrote a couple of articles about the extremely poor
macro plugin I wrote for Blosxom.
([1]
[2]). The feature-poorness of
the macro system is itself the system's principal feature, since it
gives the system simple behavior and simple implementation. Sometimes
this poverty means I have to use odd workarounds to get it to do what
I want, but they are always simple workarounds and it is never hard
to figure out why it didn't do what I wanted.
Yesterday, though, I got stuck. I had defined a macro, -> , which
the macro system would replace with β. Fine. But later in the
file I had an HTML comment:
<!-- blah blah -->
and the macro plugin duly transformed this to
<!-- blah blah -β
creating an unterminated comment.
Normally the way I would deal with this would be to change the name of
the macro from -> to something else that did not conflict with HTML
syntax, but I was curiously resistant to this. I could not think of
anything I wanted to use instead. (After a full night's sleep, it
seems to me that => would have been just fine.)
I then tried replacing --> with --> . I didn't expect
this to work, and indeed it didn't. Those &# escapes only work for
text parts of an HTML document, and cannot be used for HTML syntax.
They remove the special meaning of character sequences, which is the opposite
of what I need here.
Eventually, I just deleted the comment and moved on. That worked,
although it was obviously suboptimal. I was too tired to think, and I
just wanted the problem out of the way. I wish I had been a little
less impulsive, because there are at least two other solutions I
overlooked:
I could have defined an END-HTML-COMMENT macro that expanded to
--> and then used it at the end of the comment. The results of
macro expansion are never re-expanded, so the resulting --> would
not have been subject to further replacement. This is ugly, but
would have done the job, and I have used this sort of technique
before.
Despite its smallness, the macro plugin has had feature creep over
the years, and some of these features I put in and then forgot
about. (Bad programmer! No cookie!) One of these lost features is
the directive #undefall , which instructs the plugin to forget all
the macro definitions. I could have solved the problem by sticking
this in just before the broken comment.
(The plugin does not (yet) have a selective #undef . It would be
easy to add, but the module has too many features already.)
Yesterday morning I asked my co-workers if there was an alternative
HTML comment syntax, or some way to modify the comment ending sequence
so that the macro plugin wouldn't spoil it. (I think there isn't, and
a short look at the HTML 5.0 standard didn't suggest any workaround.)
One of the co-workers was Tye McQueen. He said that as far as he knew
there was no fix to the HTML comments that was like what I had asked
for. He asked whether I could define a second macro, --> , which
would expand to --> .
I carefully explained why this wouldn't work: when two macro
definitions share a prefix, and they both match, the macro system does
not make any guarantee about which substitution it will perform. If
there are two overlapping macros, say:
#define pert curt
#define per bloods
then the string pertains might turn into curtains (if the first
substitution is performed) or into bloodstains (if the second is).
But you don't know which it will be, and it might be different each
time. I could fix this, but at present I prefer the answer to be
βdon't define a macro that is a prefix of another macro.β
Then M. McQueen gently pointed out that -> is not a prefix of --> .
It is a suffix. My objection does not apply, and his suggestion
solves the problem.
When I write an Oops post I try to think about what lesson I can learn
from the mistake. This time there isn't too much, but I do have a
couple of ideas:
Before giving up on some piece of software I've written, look to
see if I foresaw the problem and put in a feature to deal with it.
I have a notion that this would work surprisingly often.
There are two ways to deal with the problem of writing software
with too many features, and I have worked on this problem for many
years from only one direction: try to write fewer features. But I
could also come at it from the opposite direction: try to make
better use of the features that I do write.
It feels odd that this should seem to me like a novel idea, but
there it is.
Try to get more sleep.
(I haven't published an oops article in far too long,
and it certainly isn't because I haven't been making mistakes. I will
try to keep it in mind.)
[Other articles in category /oops]
permanent link
|