6月号で紹介した誕生日問題だが、読者の方からお便りをいただいて、年齢計算に関しては法律で、誕生日の前日に満年齢が増えるという認識でよいそうである。 簡単に考えれば、1月1日から12月31日までを1年というのであって、次の年の1月1日になったら、1年と1日目、というような考え方をすると分かりやすい。
では誕生日を祝うというのは一日ずれているのか、というと「誕生日というのは単に誕生した日を祝うのであって、歳がくり上がった日の祝いではない」と割りきるのが合理的だと思う。 ろうそくは、その時点での年齢の数だけ立てればよいのであって、前日に年齢がくり上がってしても、べつに差し支えないわけだ。
考えてみたら、これって水泳の競技みたいなもので、最後の一瞬というのは手が届けばいいというわけだ。もし身長49mの選手がいれば、50mプールの場合、1m泳いでターンして1m泳いだら100m泳いだことになる。
5月号なのだが、RIMNETのPhinloda's Pageで自動的に更新マークを削除するというアイデアを紹介した。 これはちょっと手違いがあってうまく動いていないのだが、もう一つ大問題があるというのでご指摘いただいた。List 1のようなプログラムを書いたのだが、mainの戻り値は0〜255だから365日をカバーできないのではないか、というのである。
---- List 1 ---- |
/* today.c */ #include <time.h> int main(void) { time_t t; struct tm *st; t = time(NULL); st = localtime(&t); return (st->tm_year - 96) * 365 + st->tm_yday; } |
調べてみると、mainの戻り値の解釈というのは処理系依存であって、確かにSun OSではmainの戻り値は0〜255なのである。 つまり、256という値を戻しても、C shellから値を見ると0になってしまうのだ。これは困った。
でも、考えてみると、この値は1週間経過したことの判断にだけ使っているのだから、前日の差だけが問題であるとすれば、あまり慌てることもなかった。 つまり、元のawkスクリプトはList 2のような処理で1週間の経過を判定している。 書かれている日付より7日以上経過していれば、その行を削除するのである。
---- List 2 ---- |
# awk スクリプトの一部 if (now - up >= 7) { delcount++ } else { print > tmpfile } |
これが毎日実行されていれば、残っている行は経過日数が6日以下になるわけで、100日とか200日離れたデータはないと考えてよい。 つまり、引き算した結果は、常に0〜7の間であると考えてよいのである。 この状態で、todayコマンドが戻してくる値がいきなり0になった場合、HTMLファイルのデータとしては、250前後の値が日数として得られているはずだから、引いた値はマイナスになる。 しかし、経過日数がマイナスになるわけはないのである。こういう場合は、256+αとなるべき所が0になっていると解釈すれば、要するに256を加算した値を考えればよいのである。 これでまだマイナスなら、さらに256足せばいい。
というわけで、改良したのがList 3なのだが、これって今から10年後のことを想像すると随分不気味なコードではある。 こんなことする位なら、最初からC言語で全部処理すれば、という発想の方が自然である。
---- List 3 ---- |
# awk スクリプト修正版 while (now < up) now += 256 if (now - up >= 7) { delcount++ } else { print > tmpfile } |
リアクションが分からないというと、このような雑誌連載もそうであるが。 それはさておき、Phinloda's pageの場合、例えば「混沌の廃墟にて」というネットに連載した文章を持ってきている。本家の「混沌の館にて」とは何の関係もないのでお間違いのないように。 最初にネットに掲示した文章をHTMLにしてWeb pageにするのには、大変な労力が…という程でもない。 ただ、面倒なことには変わりない。具体的には、まず、連載した文章そのもののHTML化が必要である。 しかし、それだけでは他から参照する時に直接URLを指定することになって面倒なので、 他からのリンクを作るということになる。 ここからが大変なのだ。index.htmlと、ruins.htmlと、rlist.htmlという3つのデータを修正することになる。 3つのデータの整合性が取れないと、こっちで更新したがこっちから飛ぼうとしたら飛べない、という変な事態に陥ってしまうのだ。
そこで、この更新処理を自動化することにした。List 4のように変更箇所のみ記述したデータファイルをまず作っておく。 (*1)
---- list 4 Web page 変更用データファイルの内容 ---- |
header_level:3 title:<LI><A HREF="ruins.html">混沌の廃墟にて</A> comment: <A HREF="http://www.niftyserve.or.jp">NIFTY-Serve</A> <A HREF="http://www.niftyserve.or.jp/CM/Forum/fprog/index.htm">FPROG</A> 不定期連載の言いたい放題エッセイ number:219 subject:安易な実名発言は無責任ではないか (2) comment2: 実名を出したいのなら完璧に住所連絡先まで特定できるようにしないと迷惑だ。 |
この後、あるプログラムを実行すると、前述の3つのデータファイルが更新されるという仕組みである。 例えば、このデータからは、index.htmlの内容の一部をList 5のように変換するのである。
---- List 5 変換例 (index.html の一部) ---- |
<H3> <LI><A HREF="ruins.html">混沌の廃墟にて</A> <IMG SRC="update.jpg" ALT="Update">(1996-07-07) </H3> <A HREF="http://www.niftyserve.or.jp">NIFTY-Serve</A> <A HREF="http://www.niftyserve.or.jp/CM/Forum/fprog/index.htm">FPROG</A> 不定期連載の言いたい放題エッセイ <BR> <A HREF="ruins/ruins219.html"> No.219「安易な実名発言は無責任ではないか (2)」</A> 追加<BR> <P> |
え、殆どそのままじゃないかって? それは甘い。 これを手作業で修正するとどこを間違うかというと、例えば、「<A HREF="ruins/ruins219.html">」の中の数字が219なのに、うっかりその後の「No.219」の数字が218だったり、…というような凡ミスが続出するのだ。 これに気付いて連絡してくれる人もいて助かるのだが、中には気付きにくいミスなんてのもあって、数週間放置したまま、というのもある。 NIFTY-Serveに掲載されているメッセージだとすぐ間違いに気付くのだが、灯台もと暗しとはよく言ったものだ。
さらに、まだ2つもファイルが残っていて、それらの整合性も必要になるわけである。 なかなか神経のすり減る作業で、とても人間のやる類のものではない。 で、この処理をどう自動化するかという選択に迫られたわけだが、awk、perlという候補も検討して、結局Cで書いたのである。 なぜ今どきCか。DOSで編集しているからである。DOSから通信ソフトを起動して、そこからVz Editorを動かし、シェルに抜けて処理して、…という感じになるのだ。 こうなると、少ないメモリで動作する必要があるわけで、awkだとメモリが足りなくて処理できなかったりするので…と、書いていて情けなくなるような環境だが、ま、こんなものだろう。メモリが足りないといっても、ThinkPADでも11MB、デスクトップのマシンには64MBも入れてあるのだが、DOSからだとちょっと足りないという感じで、何か使い方が間違っているんじゃないかと言われれば、そういう気がしないでもない。 (*3)
(*1) orからneへの移行により、1999年4月から、niftyserve.or.jp というドメインは使えなくなり、nifty.ne.jpとなっている。 サービス名称はもっと前にNIFTY SERVEと変更されたが、当時はNIFTY-Serveだった。 さらに1999年11月に@niftyという名称になった。
(*2) 1999年現在の環境は、VAIO 505RX、メモリは128MB搭載してあり、OSはWindows 98である。 同様の処理はおおむねCygnus Win32などに移行していて、文字列処理は日本語化されたperlを使うことが多い。