アクマくんにお願い:2000年04月分

Last-modified: Wed, 03 May 2000 03:17:40 JST

[static,style:furuta,jconv:jcode,cache:on]
powered by tds-Tomsoft Diary System 1.01-beta0


[トップ(一覧)] [最新版] [<<前月] [今月] [翌月>>]

2000年04月02日()

ふじみ野

幸さん.age++ で、ふじみ野のファミレスでお祝い。 アウトレットモール「リズム」でお買物。 期待していたヴィレッジヴァンガードふじみ野店はつぶれていて、ずがん。


2000年04月03日(月)

博多天神

ねぎラーメン(細麺) + 替玉。 のちに作戦会議。

scsi_low

みつながさんの手による 新しい NetBSD/pc98 ベースの scsi_low の CAM 化が動作したらしい。 これによって、ncv, stg だけではなく、Ninja SCSI をサポートする nsp や、 FreeBSD(98) の古い bs を置き換える ct の CAM 化へも大きく近づいたことになる。


2000年04月04日(火)

inbox 掃除

とうとう、フォルダのあるファイルシステムが満杯で inc に失敗する までになってしまった。inbox に 30000 通程溜ってるので、お掃除する ことにする。

refile しまくって、4000 通まで減らした。ふぅ。 うーむ、SPAM も積れば山となる、というか、 掃除をすると結構欝陶しいね。

次のお仕事

どうも確定らしい。 という訳で、 どうも JAVA 屋さんから network 屋さんにクラスチェンジ?


2000年04月06日(木)

kterm

kterm とか xterm には、title や icon 名を変更する エスケープシーケンスがありますので、 それを使えば ディレクトリ名を Window Titile に表示させることもできるんじゃないかな。

bash だと、こんなんでできますね。

function cd
{
	builtin cd $1 || return 1
	setdir ; return 0
}

function pushd
{
	builtin pushd $1 || return 1
	setdir ; return 0
}

function popd
{
	builtin popd $1 || return 1
	setdir ; return 0
}

function setdir
{
	echo "^[]0;${PWD}^G"
}

setdir

<ESC> ']' '0' ';' 文字列 <BEL> というエスケープシーケンスを kterm に送ると、icon 名と title に指定した文字列が設定されます。 '0' の代りに '1' だと icon 名だけが変化、 '0' の代りに '2' だと title だけが変化するみたいです。 では、健闘を祈る。


2000年04月07日(金)

体調は悪くないけど、とある事情で一回休み。

花粉症

二週間前に処方してもらった薬が切れてしばらく放置していたら、 またかなり症状がぶりかえしてしまった。 休みだったので午後からかかりつけの耳鼻科に行って 薬の処方だけしてもらう。 しかし平日に関わらずこの混みようは何だ?

修行

昨日くらいから rcsfile(5) や vc.el や emerge.el を読んでいる。 何をしようとしているかは秘密。\


2000年04月08日(土)

花見

今日は幸さんも同伴で、お弁当を作ってもらった。 いろいろ手間どって 11 時ごろ自宅を出発したので、 現地到着は 12 時半ごろ。 どうも例年の場所はすでに allocate 済みで別の場所らしい。 適当に探すと、面子発見。

適当にいろいろ飲み食べしつつ、自己紹介など。 午後3時前後には50人くらいの規模だ。 なかなかすごい面子だった。 某金髪の人が guest で来たりして、組長と金髪ペア。

作戦会議で予定していたバケツフルーチェは好評だった模様。

どうも幸さんの体調がよろしくないようで、16 時半ごろ離脱。 少し話し足りない気もするが、仕方がない。 大岡山駅前の風月堂でお茶を飲んで休んだあと、帰宅した。

花粉症

花見で長時間屋外にいたせいか、 花粉症が悪化して、大量のテッシュを消費する。 薬もほとんど効いてくれない。 鼻がつまって頭がぼーっとするので、作業ができない。ズガン。


2000年04月09日()

謎作業

うー、emacs-lisp 忘れている。

調査のため rcslex.c とか読むけど、 コーディングスタイルが前近代的で疲れる。:-) しかもこれってば Latin-1 を仮定しているし、 よくわからなく内容が冗長で、なんだかなあ気分。

とりあえず、パーザは実装してみたけど、未だバグがいる模様。


2000年04月11日(火)

謎作業

将来のためにメモ。

_ rcsfile(5)

RCS ファイルの木は、(差分の適用に関して) 幹(trunk)は逆順、枝(branch)は正順という基本ルールがある。 これはもちろん、効率のためであって幹の先頭(head)は 生テキストの形で記憶されているので、 取り出すコストが低くてすむ。 任意の revision を取り出すには、 まず幹の先頭からを根(root)に向って逆順に進みながら差分を適用する。 これで幹にある revision は取り出すことができる。 幹以外の枝にある revision は分岐点から今度は正順に差分を適用して 得られる。

RCS ファイル中の各 revision 毎のフィールドには、

の情報がある。このうち、log と text だけは 別区域にまとめられている。 つまり、最初は log と text 以外の revision 基本情報が順に並んでおり、 全ての revision の基本情報の後にまとめて revision の log と text が 並んでいる。詳しくは rcsfile(5) の BNF 参照。 これは効率のために長くなりがちな log と text を後に回して、 revision 木構造を構成するのを効率よくするためだろうと思う。

next フィールドは差分適用順序に関しての次の revision 番号を指している。 つまり、幹では一つ前の revision だが、枝では次の revision を指す。 branches フィールドはその revision から派生した枝の最も古い revision を指している。 幹の先頭から始めて、next と branches を再帰的に手繰ると 全ての revision に到達することができる。

rcsfile(5) には特に記述はないようだが、revision はこの差分適用順に 並んでいる。つまり、幹の部分は逆順に、枝は正順に並んでいる。 そのため next や branches は常に前方参照である。 また、next 方向優先で、その後に枝が並んでいる。 このため、任意の revision のテキストを得るには、 各 revision ごとにファイルを読む形式のプログラムであっても、 逆方向に seek する必要はなさそうである。 しかし、記述がない以上、この順序を仮定するのは得策ではなさそうだ。

text は幹の先頭だけは生テキスト (ただし、中の "@" 文字だけは escape される。 以下、差分や log 他、rcsfile(5) の "string" は全てそう)で、 それ以外の text は全て差分情報である。 差分情報は、diff(1) の -n オプションそのもの(の "@" を escape したもの) である。 差分情報に関しても rcsfile(5) には直接の言及がない。

deltatext ::= {difftext}*

difftext  ::= addtext
              deletetext

deletetext ::= "d" number number "\n"

addtext   ::= "a" number number "\n" {freeform-line "\n"}+

「"d" number1 number2」は、number1 行目から number2 行分を削除せよ、 という意味で、「"a" number1 number2」 number1 行目の後に number2 行分 を追加せよ、という意味。 "a" 行の後には number2 行分の挿入行(freeform-line) が置かれている。 number1 はファイルの先頭行の場合は 1 行目。それより前に行を挿入するには、 "a0 ..." というような記述になる。 また、number1 は、そこにある差分適用前での行番号である。 頭から順に差分を適用すると、それより後の行の行番号は変化するが、 その変化する前の行番号で指示する。 ed にあるような "c" は "a" と "d" の組み合わせで指示する。

_ さらに謎

いくつかファイルを食わせてみたけど、パーザは何とか動いているようだ。

次はパーズしたデータを格納しておく必要がある。 まずファイルに global な情報と、revision 毎の情報。 vc-hooks.el を覗いていたら、 自前の obarray に intern したシンボルの plist にデータを格納しているようなので、それをまねてみる。 revision 毎の情報は、revision を obarray に intern して引出す。 ファイル全体情報は、revision 番号にならない文字列を intern してやる。 obarray を RCS ファイル毎に記憶しておく必要があるが、 これは buffer local 変数に入れておけばよさそう。 log や text などの string は emacs lisp の文字列として取りだすと 余計なコピーが発生するので、代りに marker でもって記憶しておくことにしよう。

とりあえず、情報を格納してから revision 番号の tree を構成する コードを書いてみるが、どうやら動いてそうだ。

mew のような形で表示するには、 Windows configuration を操作すると良いようだが、 code を読んでもさっぱり理解できないので、さらに精進が必要。

サイトローカルなアンテナ

まあ、メンバーが少ないので はうンサーバユーザの日記とか一覧のように大きなコストダウンになるかというとよくわからないのです。 また、そこの情報は全部 *BSD Diary Linksから取得できる \ 訳で、それと比較して意味があるの? って話もあります。 ですから、 はにゃ〜ん あんてなのようにより頻繁に更新することで、 差別化して(他のアンテナに DI 情報などを)利用してもらう というのはあるかもしれません。

某メール

というか、某誌の某 ML ですが、 draft を書いたのだが、 これに反応したら確実に今年のゴールデンウィークも潰れる予感。(;_;)

Java 環境

そうですね。Java のデバッグは確かに困難です。 私も以前は println() でデバッグしてましたけど、 やはりある程度(すでに十数万行ある) の規模になると良質のデバッガが欲しくなります。 以前にも書いたけど、単に Java のデバッガとして、 Visual Cafeはおすすめです。VC++ のデバッガのレベルがどの程度かはよくわかりませんが、 少くとも emacs + gdb mode での C のデバッガ程度には便利です。 (変数の browse 機能が強力なので、もっと便利かも)


2000年04月13日(木)

ローカルアンテナ

そかそか CGI でその場で調査している訳ですね。なら、意味はあるんじゃないでしょうか。

なるほど、SSI だけで他にプログラムやスクリプトが一切いらないのがミソなわけですね。

謎作業

次は revision バッファ中の特定の revision を取り出して 表示させるか。 何だかこういうコンテキストとしてカレントバッファを持っていて ほとんどのバッファ操作がカレントバッファに対して、っていう パラダイムはどうも慣れない。

とりあえず、revision の表はバッファ上に表示できるようになったので、 やぱし、キー操作一発で枝全部見せたり隠したりしたいよね。 emacs って Outline mode が似たようなことをしてるよな、 という訳で、outline.el を読む。 むむ、何すか、この make-overlay つーのは。つーか謎。 info で (elisp) へ行って、ふむふむ。 ほー、emacs 20 からは Overlay なんつー便利なものがあるのね。 invisible な Overlay を作って被せてやると、あら不思議、 テキストはあるのに見えなくなってしまうと。 これを使ってみることにしませう。


2000年04月14日(金)

肉体会

肉、食った。


2000年04月15日(土)

お休みの日

寝てた。一日じゅう。


2000年04月16日()

お休みの日

寝てた。一日じゅう。

我ながらすごいと思う。 どうしたらこんなに自堕落になれるのか。 先週異様にテンションが高かった反動かな?


2000年04月17日(月)

今週の目標

はりきらない。

にせ

ぐはぁ。きなくさいです。 うう、勉強します。

謎作業

煮つまってきてる感じがする。 このへんで何となく考えていることをちゃんと 書き下した方が良いかも。

指定した revision をバッファ中に取りだしたい。 これは幹の先頭から始めて順次 delta を適用していけば、 どの revision でも計算できる。

が delta の適用を素直に実装してしまうのは効率が悪い。 一旦バッファに突込んでから一部テキストを削除したり追加したりするよりは、 ポインタレベルで挿入するべきテキスト(の部分)を計算しておいてから、 最後にまとめてバッファに挿入してやる、という方法である。

バッファに詰めこむテキスト行は全て RCS ファイル中にある。 そこで、RCS ファイルを適当なバッファに保持しておいて、 そのバッファ自体は read only にしておいていじらない。 その上でバッファへのマーカをポインタとして扱うことにする。 ある revision のテキストをポインタの形 のかたまり(chunk、いくつか行が集まった単位)で保存しておいて、 必要に応じて chunk の集合からテキストを組み立てることにする。

chunk 集合形式で表現しておくことにしておくと、 単なるテキストだけじゃなくて他の作業にも調子が良さそうだ。

さて、chunk 表現の構成アルゴリズムを考えないといけない。 まず最初は幹の先頭から始めて、順次幹を遡れば幹の情報は全部得られるはず。 幹の先頭はバッファ全体を表わす一つの chunk で表現できる。 それに delta を適用した場合、"d" や "a" に対応する chunk が 分割される(こともある)

"d" ではその部分のテキストがそれより前では消える。 つまりその次の revision で生成された部分だということがわかる。 "d" が chunk の全体を覆っていれば、 chunk 全体に「生成された revision」の情報を付加する。 "d" が chunk の一部を指していれば、 その部分で chunk を分割する。 あるいは "d" の覆い方によっては三分割される。 いずれにしろ、"d" に対応する部分には生成された revision の情報が付加される。 そして、delta を適用された「前」の revision には chunk は入らない。

"a" でテキストを挿入する部分は、 挿入されるテキストを指す chunk を新しく生成する。 "a" がちょうど chunk の境界を指していなければ、 そこで chunk は分割される。

この分割を繰り返して最終的に幹の「根」つまり最も古い revision (ふつうは revision 1.1) に至ればこの分割は終りになる。 この時点で根を構成している chunk の出自が明かになる。 生き残っている chunk を生成した revision は、幹の根だから、それを設定する。

枝の部分の delta は幹とは反対に正順なので、処理はもっと簡単。 分割されて出自が変ることはない。 新しく "a" で chunk を追加した場合のみ、 出自情報を設定すればよい。

分割した場合のデータ構造の扱いだけど、 分割前の chunk を親として分割後を子とする木構造で持ってりゃ 何とかなるだろう。

うむ、ずいぶん見通しが良くなったかな。 じゃ実装しよ。

反省

うう、どう考えてもはりきっとるな。いかん。

さらに謎

また思い出した。

普通 diff(1) は最小差分を計算してくれる。 (すくなくとも、Version 7 の diff(1) はそのはず。 ただし、最小差分が必ずしもプログラムの差分を表現するには 適切でないこともあるとかで、GNU diff が最小差分を計算しているか どうかはよく知らない)

さて、最小差分の合成が最小差分とはならないことがある。

 A       A       A
 B  ->   B'  ->  B''
 C       C       C

 1.1     1.2     1.3

という変更を考えた場合、1.1 と 1.3 の差分は「B -> B''」だけども、 ここで「B == B''」というケースを考える。 (こういう変更、つまり一旦施した変更を次の revision で元に戻すことは 極めてよくあること。また、枝の分岐点を考えてもこのような差分を 考えることは有用だと思う) この場合は前の「chunk」アルゴリズムでは差分を計算する方法は かなり不適切。 だから、別途「B == B''」状態(あるいは「B と B'' が B' よりもずっと近い」状態) を検出して、それなりの処理をしてやる必要がある。 具体的には、B と B'' の両端一致部分を剥ぐだけでも、 ずいぶんましになるはず。

しかしこの処理はある意味「小手先」に過ぎない。 結局、厳密な意味で「最小差分」を計算するには 1.1 と 1.3 のテキスト全体に対して diff(1) のアルゴリズム を適用するしかない。 効率の点からも実装の点からもこれを emacs lisp で実現するのは 馬鹿らしい。 かと言って diff(1) を呼び出すのも本来の目標から言って不本意。 diff(1) を呼び出すぐらいなら、いちいち自前で rcsfile(5) をパーズ しないで co(1) や rlog(1) を呼び出した方が良かろう。

というわけで、この問題は多分 BUGS 項目として認識しつつ、 「仕様です」と言いはなってつき進むしかないだろうな。

さらに反省

しまった。またはりきってしまった。反省。


2000年04月18日(火)

失敗

うーん、完全に私のミスです。 私が甘かったです。 以降気をつけます。


2000年04月19日(水)

にせ

絶賛ぽしごと中。反応遅くてごめんね。


2000年04月20日(木)

謎作業

_ emacs lisp

しばらく書いててだんだん慣れてきてるんだろうか。 うーん、何がいやかって、emacs lisp の loop 構造が 基本的に while しかないことなんだろうな。 Common Lisp の do とか prog とかまでは言わないが、C などの break や return のような無名の局所脱出が欲しいなぁ。 要するに、sequence 構造を scan しつつ、何かを見つけるというコードって 極めてよくあるんだけど、C なら

while (sequence がある) {
    ...
    if (発見) {
        発見の処理;
        break;
    }
    ...
}

というのは定石中の定石だと思うけど、これが書きづらい。

(while (and sequence がある (not found))
    ...
    (if 発見
	(progn
          発見の処理
          (setq found t)))
    (if (not found)
        ...))

てな形なんでしょうかねぇ。 いや、(require 'cl) で do やら return やらを使えば良いのは承知の上で、 cl には依存したくないですし。 かと言って throw と catch をこんなケースで使うのは大げさだし、 第一名前を考えないといけない。

_ diff -n

diff(1) の rcsfile(5) 専用 output "-n" だけども、 眠い頭で解釈コードを組んでいて訳わかんなくなってしまった。 通常の diff の "c" 相当、例えば 10 行目から 13 行目までを "hoge hoge" という1行で置き換える場合、

d10 4
a10 1
hoge hoge

となる。 ここで、「d10 4」は 10 行目の先頭から、4 行分を削除という解釈で 良いのだが、「a10 1」は 10 行目の 、すなわち 11 行目の先頭から 1 行挿入、という意味なのだな。 「d10 4」と言った時の "10" の指す場所とは違っていて、 すでに削除されてしまった領域内の行を指していることになる。 なまじ同じ数字なので思いっきり混乱してしまった。 本当は挿入するべき本来の場所を指して(つまり「a9 1」とする)ほしいものだけども。 このせいで、"a" の処理に、指された行は削除されていないかどうかを 判別する必要が出てしまった。 面倒くさい。


2000年04月21日(金)

Java

Java の疑問ですが、String と StringBuffer が貧弱というのは一部同感。 ただ、そういう機能が必要なら新しくクラスを書いてしまえば良いだけの話だと 思います。String からと String への変換関数を用意しておけば、 実用上ほとんど問題ないです。

Interger や Character は「ラッパークラス」と言いますね。 int型 や char型がクラスでなくなっているのは、 ひとえに効率のためでしょう。 クラスであるには、最低 Object を継承してなくちゃなんないわけです。 で、その手の継承を実装したりするには *1オブジェクトの内部の実装では、 オブジェクト毎の情報の他に クラスへのポインター領域がどうしても必要になってくるのです。 しかして、char 型なんて Unicode なら 16bit で十分 *2なわけで、かなり余計なオーバヘッドなんですね。 だから、必要な場所だけに限定する目的でクラスになってないんだと思います。


*1:クラス毎に hashCode() とか toString() の実体は違うので、 クラスはその情報を知っていないといけません。 各々のインスタンスは属するクラスによって実行する hashCode() とか toString() の実体が違うので、 各オブジェクトは自分が属するクラスが何かわかるための情報を 必ず持たねばなりません。 それは普通はポインターで実装されます。
*2:UCS4 使えよと思うけど。

emacs lisp

どうも ご意見ありがとうございます。 某chatでもつっこみをいただきました。 まず、loop 変数に終了を示す値をぶち混んでしまえ、というのは当然考えました。 (これは 某 chat でも指摘された) ただ私の考えている「sequence 構造」というのは lisp の sequence に限らず、 もっと一般的な列をなすもので、(例えば、file read とか) 一般的にその状態を変更して良いものとは限らない、 というのもあります。また、終了時の sequence 状態を loop を抜けてから 参照したい時もあるでしょうし、 ケースバイケースですが、一般的に使えるテクニックとは言えないと思います。 ちょっとトリッキーですよね。

次のは、某chat でのつっこみ。

(while (and sequence (or (not (ok-p (car sequence)))
                         (progn (do-something (car seqence)) nil)))
   (setq sequence (cdr sequence)))

つまり、主たる処理を while 本体で実行するのではなくて 条件中で実行してしまうという方法。 たぶん、こっちが正統(伝統的?)な方法なんだろうなあと思います。 というか、「cl.el 使いたくねー」なんてダダをこねるんだったら、 これくらい書けるリテラシーを身につけるべきなんでしょうな。

という訳で、もうちっと cl.el 使わない方向でがんばってみます、です。


2000年04月22日(土)

引用

む、むむむむ、ちょっと待って下さい。 確かにある一定の条件が満されれば引用は可能ですが、 この場合 それが満されていないように思えます。

以下、「著作権法 第32条(引用)」を引用します。

公表された著作物は、引用して利用することができる。この場合において、 その引用は、公正な慣行に合致するものであり、かつ、報道、批評、研究その 他の引用の目的上正当な範囲内で行なわれるものでなければならない。

(以下略)

miwada さんのおっしゃる「引用」が具体的に cdplay のソースコードを どうすることか日記を読んで詳しくはわかりませんでしたが、 CD-DA の演奏部分の実装のために cdplay のコードの一部を 複製するのであれば、 それは「報道、批判、研究、 その他の引用の目的上正当な範囲内」からは 逸脱しているのではないかと思います。 (少くとも、報道、批判、研究、あるいはそれらに並べられるような 範疇には入らないでしょう。 もし逸脱していないとすると、 かなりすごいことができちゃう気がします。 私の知る限り、そういうことしている「慣行」は存じません。)

miwada さんは引用という言葉を使われていますが、 コードの一部あるいは全部を、 (報道、批判、研究等の目的のためではなく、その コード本来の動作をさせるために) 複製することは、一般には「引用」とは言わないと思います。

もちろん、cdplay の著作者は(一定条件付きで)コードの 使用を認めているので、その条件に従ってコードを「使用」すれば 良いのだと思います。 もちろん、「使用」には「一部複製」も含まれます。

フリーソフトウェアでよく出会う「引用」は、 コードの patch でしょう。 context diff などは patch 適用元のコードの一部を含んでいますが、 「このコードのこの部分をこう変更すると、 さらに良くなる」という批評に相当しますから、 引用として適切です。

ところで、著作権法などは LEC の 日本の法令のページで読めるので、必要ならどうぞ。 まあ、世の中にはプログラマさん向けや、 最近は web page の作者向けの著作権法の 本っていくつか出てますので、 一冊買っておいて損はないと思いますけど。


2000年04月23日()

火祭

深夜になにげなく NHK を見たら、 日本の祭「岐阜手力雄神社火祭」という番組を放送していたので 思わず見てしまった。 全然チェックしてなくて、何だか見覚えある光景が出てきて驚いたのである。 実家はここの氏子じゃない(地区が違っていて別の神社の氏子なのである) ので、家族やらご近所が出演しているわけではないけども、 御輿を担いだり半鐘を鳴らしている連中のほぼ全員は 私と同じ中学を卒業しているはずなのである。 誰か知人がいないか見てたけど、結局発見できなかった。

まあ例年祭の日は 東海地方の夕方のニュースで取り上げられる程度には有名なのだが、 そんな規模の大きい祭じゃない (第一、境内が狭いから国府宮みたいに観客が訪れると困る) し、全国放送で見られるとは思わなかった。 どうやらハイビジョンの方が本放送で、 そっちは生放送だったらしい。 多量の火の粉を浴びながら御輿を担いだり半鐘を鳴らしてるので、 初めて見る人は驚くかも。 NHK もなかなか目のつけどころがよい。

って言うか、地元というか近所にありがちというか、 20年も住んでいたくせして通して全部見たことがなかったし、(^^; 解説付きだったりして、いろいろ新鮮な発見があったりする。 しかし、最近の御輿はアレ、というか、 ドラえもんやらたれぱんだが火を吹き上げる様はかなりシュールだ。


2000年04月24日(月)

スーツ

ほぼ一年ぶりくらいに着たら、 見事にきつくなっていたので、(^^;; 急拠ボタンを縫い直してもらってから家を出る。 っていうか、 最近カロリー高すぎるイベントに出すぎかも。(^^;

「っ!!! ゛〜〜〜」 <- 心の叫び マジで驚いた。(滝汗出まくり)


2000年04月29日()

distfiles

私も同感ですが、distfiles を CD-ROM に収めるのはなかなか大変だと思います。

$ cd distfiles
$ du -sk
4952128 .
$ 

5GB だから、8 枚組になりますね。 (unlink してないファイルがあるので、 もう少し少くて済むかも) 必要なものを選ぶのも必ずしも簡単じゃないですし。

ちなみに、私は 56Kbps modem でテレホーダイ時間帯に FreeBSD の distfiles をフルミラーしてます。 最初に何とか distfiles をコピーしてしまえば、 不可能じゃないっす。


[トップ(一覧)] [最新版] [<<前月] [今月] [翌月>>]

このページは、

Copyright(C) 1999,2000 Atsushi Furuta <furuta@bsdclub.org> All rights reserved.