いや、mconv は日本語をひいきするから htree につけるのは不適切か。
HTree.parse(uri) としたときには open-uri が提供する charset で $KCODE にデコードするようにしよう。 guess したいときには guess するような charset メソッドを仕掛けることにして。
将来的に m17n になった場合は... デコードしないで済むケースが増えるだけか。 どーせ iso-2022-jp とかはデコードしない限り扱えないわけだし。
いや、htree はすでに $KCODE が EUC というのを内部コードが EUC-JP であると解釈してるから、すでに日本語をひいきしてるか。 EUC-KR という可能性だってあるわけだし。
ふむ。これの問題は出力側だな。 入力側は、 $KCODE 毎に扱える(複数の) charset を保持しておけば、 外部資源の charset に対して、扱えるどれかに変換すればいい。 例えば次のように出来るだろう。
RepresentableCharset = { 'UTF8' => ['UTF-8'], 'EUC' => ['EUC-JP', 'EUC-KR'], 'SJIS' => ['Shift_JIS'], 'NONE' => ['ISO-8859-1', 'ISO-8859-2', ...], } ... input = input.read if input.respond_to? :charset and input_charset = input.charset unless RepresentableCharset[$KCODE].include? input_charset RepresentableCharset[$KCODE].each {|internal_charset| begin input = Iconv.conv(internal_charset, input_charset, input) break rescue Iconv::Failure end } end end
しかし、出力側では、$KCODE からは String の中身がどの charset か一意に決定できないので、 エンコードするときの入力 charset がわからない。 これを保持するのは String と charset を対にしてもってまわらないといけないので面倒臭い。 てゆーか、m17n でそうなるはずなのだから、 現時点でアプリケーションでそうする気にはならない。 というわけで、m17n が来るまでは日本語をひいきして済ますことにしよう。
しかし、m17n になったらなったで面倒臭いことになりそうな気はする。
木があったとして、それを XML として出力する場合、 現在は内部エンコーディングから目的とするエンコーディングに変換する Iconv オブジェクトを作り、 木をトラバースしながら Iconv オブジェクトに突っ込んでいく。 しかし、木の各所に入っている String でエンコーディングが異なっていて、 内部エンコーディングが一意に決まらないとしたら、 いったいどーすればいいというのだろう?
うぅむ。getrlimit, getrusage, setrlimit であった。
昨日は setrusage と言ってしまった気がするが、 考えてみると setrusage というのは根本的におかしいよな。 たとえば、ru_nswap を増やしたら、 いきなり swap を始めるのだろうか。 あるいは、ru_nsignals を減らしたら、 今までに受け取った signal がなかったことになるのだろうか。
... うぅむ。user time を得るには Process.times があったか。
そういえば、やっぱり静的生成だよね、という話があった。
が、ローカルで生成して送り込むか、リモートで生成するかは人によるようだ。
住居の近くの本屋の閉店が 22:00 から 23:00 に延びた。よきかな。
そーか。本当に欲しかったのは setrlimit だったのだ。 なんで欲しかったかというと coredumpsize を unlimited にしたかったから。
今日 datasize とかを制限していて思い出した。
ふと、time_t tv_usec というのを探してみると、いくつか見つかる。
というように、tv_usec が time_t なシステムはいくつかあるようだ。 まぁ、time_t が signed ならとくに問題は無いだろうし、あり得るか。 (SUPER-UX というのは「スーパーコンピュータSX-4/SX-5シリーズ用のオペレーティングシステムで」らしい)
また、POSIX:XSI でそう定義されているという話もある。
しかし、少なくとも SUSv2/SUSv3 での tv_usec は suseconds_t になっているので、 これは単に間違いであるか情報が古いかである。 とはいえ、もし古い POSIX でそうであったとしたら興味深い。 でも、SUSv3 の sys/time.h の項には Issue 5 で long から suseconds_t に変わったと書いてある。 それ以前に time_t から long に変わった可能性は考えられるか?
まぁ、間違いっぽいか。
ANSI/IEEE Std 1003.1 1996 Edition を調べる。
... そもそも struct timeval が無いっぽい。
かわりといってはなんだが、struct timespec はある。
POSIX 的には timeval より timespec のほうが正当なのだろうか?
今日知ったこと: ツマグロというのはサメであってマグロではない。
Apache で、URL に cgi-bin とか .cgi を含めずに CGI を起動する方法は多々ある。
ScriptAlias, mod_rewrite, SetHandler など。
しかし、どれも状況によって使えたり使えなかったりで使いにくそう。
open-uri での proxy をテストするためにひさしぶりにプロバイダの proxy server に繋げる。 が、なんかエラーが出る。
調べてみると、どうやら proxy server の提供をやめてしまったらしい。
さて、Squid は proxy なわけであるが、 proxy に URN をリクエストする場合、Host: には何をつけるべきか?
mailmerge なんていう言葉があるのか。
cvs を update する。
RDF を調べてみる。
syntax が変態だというので期待していたのだが、 細部はともかくとして基本的なやりかたは変ではない。 RDF が表現している対象はグラフで、 それを XML という木にエンコードするわけなので、 木になるようなサブグラフの集合にグラフを分割し、 各サブグラフの頂点と辺を XML の要素に対応づける。 分割したサブグラフ間のつながりは名前と参照で表現する。 まぁ、グラフを木にエンコードするときに、 グラフの構造をなるべく保存しようと思えばこんなかんじになるだろう。
さて、それはそれとして、様々な省略記法があるのだが、 そのへんはたしかに変態的といって差し支えないと思う。
というわけで今日の結論:「変態は細部に宿る」
ここ数日、追いたてられるかのように HTree の template engine を仕上げたかいあり、 それなりに API が安定したっぽいので、 五月雨も Tempura を捨てて HTree のに移行する。
とりあえず速くなったのは喜ばしい。
替える前に Tempura での展開時間をはかってみたところ、50秒くらいかかっていたことが判明した。 HTree では 0.5秒くらいなので、えぇと、100倍くらい?
全体の実行時間は、ネットワークやサーバの都合もあって変動するけれど、 昨日の log で平均すると... 55秒程度。 つまり、実行時間の大半は Tempura に喰われてたわけか。
まぁ、HTree が速いというよりは、 Tempura (あるいは五月雨での Tempura の使い方) が遅すぎたに違いない。
RFC3151: A URN Namespace for Public Identifiers
ふむ。
Last-Modified: Sun,18 Apr 2004 00:00:00
というのを返すところがあって、五月雨がしばらく動作不能になる。
まぁ、これに限らず特定のページが原因で五月雨全体に不都合が出るというのは間違っている。 本来はちゃんとエラーを隔離して、 特定のページで出るエラーが他のページや五月雨全体には影響しないようにすべきなのだが、 そういう基礎的なところがなっていないと思うと最初から作り直したい気分になってくる。
思うのだが、テンプレートエンジンも含め、 車輪の再発明な感じのを手掛けることが多い気がする。 そこで、車輪のマークでも入れようかと思ってふと家紋にその類のがあったことが思い浮かんで探してみると源氏車というらしい。
日記の類の多くはリンクを含み、そのなかのいくつかは 固定 URI (permalink) を提供する。
固定 URI かどうかを判断するにはどうしたらいいか?
テンプレートから Ruby コードに変換するのと、 そのコードを実行して XHML を生成するところの時間をはかってみる。
前者が 0.03秒くらい、後者が 0.5秒くらい。 うぅむ。とりあえず現時点ではコードのキャッシュは無意味か。
源氏車を PS で書いてみようかと考えるが、 赤本が手元にないことに気がついてやめる。
PS の図をテキストエディタで記述する場合、 「書く」と「描く」のどちらが適切か。
なんつーか並立しない。 いい加減疲れたので、テンプレート中の空白なテキストノードは基本的に全部削除ということにする。 これで前の2つはどうにかなった。 最後のはもっと使ってからまた考える。
HTree で REXML に変換するメソッドを書いた。 とりあえずこれを区切りとして 0.1 をリリース。
traverse 系がまだ揃ってないが、 traverse したいひとは REXML に変換して使えということで。
ひさしぶりに cvs.m17n.org の viewcvs から tarball を download してみると、 変なメッセージが出る。
tar tvfz で tar: Read 6144 bytes from xxx.tar.gz というのと、 tar xfz で tar: xxx: implausibly old time stamp 1970-01-01 09:00:00 というもの。
前者は良く分からないが後者は心あたりがある。 たしか tarball generation を書いたときに directory の timestamp をさぼって Unix Epoch で済ましてたような気がする。
これはよろしくないのでどうにかしなければならないが... おぉ、最新版の ViewCVS では直っているようなので、ありがたく新しくすることにする。
前者は、調べてみると GNU tar の問題らしい。 1.13.93 ではそういうメッセージが出るが、1.13.94 では出ない。 なので気にしない。
さて、新しい ViewCVS を設定していると、 root_as_url_component という設定が増えていることに気がつく。 これは cvsroot の選択を query じゃなくて path_info でおこなうもので、 複数のリポジトリを扱うときには便利であり、使うことにする。
が、そうすると単純にバージョンアップすると URL が変わってリンクが壊れて悲しい。 また、tarball も directory の時刻が変わるので、ports みたいに get した後に ちゃんと hash を検査している連中には悲しいかも知れない。
なので、別の場所に設置することにする。 せっかくなので cgi-bin も外して URL を短くしよう。
なんか腹が痛い。下痢か。
ふと思ったのだが、この痛みを的確に表現する言葉はなんだろうか。 国語辞典をひいて考えてみるが、なんだろう? 腹痛というのはたしかだがこれは大雑把で、もう少し限定された言葉はないだろうか。 疼痛じゃない気がする。
さらに思ったのだが、最近の(コンピュータに載る)辞典は、 絵が出て来たり音がなったりするわけだが、 同様に、痛みの項目をひくと、その痛みを実際に感じられるというのはどうだろうか。
cvs-info も修正する。
diff を出すときの .diff という余計な suffix も使わないようになっていることに気がつく。
tarball generation の仕様が変わっていることに気がつく。
以前は、viewcvs/foo/foo.tar.gz というような URL で foo というディレクトリの tarball を生成していたのだが、 今は viewcvs/foo.tar.gz になっている。
foo の重複がなくなったのは喜ばしい... のはそうなのだが、 foo/foo-0.1.tar.gz などというように、ディレクトリ名とは異なる 名前をつけることが出来なくなっている。
うぅむ。こちらの要求と行われた改善の両方を満たす解は思い浮かばないな。 今の仕様で満足するか、 あるいはローカルハックで以前のも受けつけるようにして誤魔化すか。
ほんとうはどうすべきなのだろう? 個人的には、tag.tar.gz と指定したときにその tag に対応したのが出て来るのがいい気がする。 でも、これは tag にバージョンだけじゃなくてプロジェクトの名前もいれるというある意味で冗長な慣習を行っていないと嬉しくない。 そうでなければ、dir-tag.tar.gz のほうがいいだろう。 dir-HEAD.tar.gz とか。
自分の要求を考え直してみると、 リリースの tarball を ViewCVS から直接生成したいわけである。 それによって、tarball を作る手間を tag を打つ手間だけに抑えたいのである。 そのためには、普通のリリースの tarball と同様に、バージョンをファイル名に含め対し、できれば展開して出てくるディレクトリにもバージョンを含めたい。
それに対して今の ViewCVS は snapshot 生成用という感じである。 ふむ。
tarball に mod_rewrite を使うという手もあるか。
いまさらだが「誰のためのデザイン?」を読んだ。
むろん、読んでいて気になるのは、 プログラミング言語やライブラリに適用したらどうなるだろうかということで、 いくつか考えた。
たとえば、なんかうまくいかないことがあったらともかく例外を出して、 プログラマに他の方法を選択させるというのは、 強制選択法と考えられるかも知れない。
ただ、基本的に即座にフィードバックを与えることはなかなか難しい。 プログラミングをテキストエディタに向かって行う限り、 動いていないプログラムを相手にせざるを得ず、 動いた結果のフィードバックを即座に得ることは難しそうなので。 まぁ、Emacs Lisp や Smalltalk は別かもしれないし、 テキストエディタでも色をつけてくれるとか、 さらには Eclipse などの統合開発環境のようなものであればいろいろなフィードバックは得られるけれど。 でも、普通のテキストエディタからでも得られるフィードバックというのはあるだろうか?
また、可視性もどうやって与えたらいいだろうか? テキストエディタが起動して、空白の画面が表示されている状況で 出来ることを可視化するのは難しそうである。 まぁ、適当なテンプレートを最初に与える wizard はそういうことを防ぐかも知れない。 それはそれとして、プログラムが表示されていたとき、 そのプログラムの改変可能性が可視になるように 言語や API を設計することは出来るだろうか?
空白を入れたいなら、   ではだめですかね。 デフォルトのテンプレートではそうやって入れてあります。
また、どうしてもどうしても生の空白を入れたい場合は、
<span _text='" "'> </span>
という手があります。
ほらこんな感じ。
% ruby -rhtree -e 'HTree.expand_template{"a<span _text='" "'> </span>a"}' <?xml version="1.0" encoding="US-ASCII"?>aa
... って動いてないじゃん。バグ?
いや、バグではなかった。quote ってのは難しい。
% ruby -rhtree <<'EE' HTree.expand_template{"a<span _text='\" \"'> </span>a"} EE <?xml version="1.0" encoding="US-ASCII"?>a a
backslash 無しで書くなら、こんなかんじか。
% ruby -rhtree -e 'HTree.expand_template{%q{a<span _text="%{ }"/>a}}' <?xml version="1.0" encoding="US-ASCII"?>a a
tarball をとって来て、 中身に configure があればインストール方法はおそらく ./configure; make; make install であり、 その結果として /usr/local/bin にコマンドが入るあろうと予想がつく。 標準化のたまものである。 (むろん、規格じゃなくてデファクトスタンダードであるが)
さて、同様な意味で、CGI スクリプトをインストールする標準的な方法はあるだろうか?
ところで、件の本によれば、標準化は最後の手段である。 (誰のためのデザイン? pp.309-310)
それよりも先に、可能ならば適用すべき原則がいろいろとある。
インストールという作業に対してはそういうのは不可能なのだろうか。 対応づけとか制約を使うことは出来ないのだろうか。
考えられる制約はどんなものがあるか。
semantic predicate というのは、 パーザ生成時には分からないが、 パーズ時にはわかる、 という情報を利用して文法の曖昧さを解決するものである。
LR でこれを行うためには conflict の解決を semantic value が利用できるようになるまで遅延しなければならない。
zyacc の semantic test は LR 表を引いて conflict に当たるところまで遅延するわけだし、 btyacc の []-action は conflict に当たった後の trial mode まで遅延できる。
さて、最近の bison には GLR が載っている。
GLR は基本的には LR で、conflict が起きたら、 その全ての可能性を同時に試すというやりかたである。 btyacc が縦型探索だとすると、横型探索だといえる。 (また、探索を合流させるため、btyacc と違って指数関数的な爆発が起こらなくなる) したがって、探索の途中で、semantic value を利用した打ちきりを行えば btyacc と同様なことが可能なはずである。
マニュアルを眺める... うぅむ。%merge でできるか?
ただ、bison は inherited attribute を yacc 以上には支援していないので、 今回の条件には合わない。$-1 で我慢するという手はあるが。
しかし、考えてみると、このへんの話は Lexical Tie-in と相性が悪いため、 Ruby に適用するのは厄介な気がする。 つまり、構文解析をどんどん遅延するということは、 相対的に字句解析がどんどん進んでいってしまうわけで、 その進んでいってしまう字句解析を構文解析側から手を出して制御するのは ちょっとどころではなく困難なんじゃないだろうか。
もちろん、Lexical Tie-in も考慮して字句解析からやり直してくれるような parser generator があれば別だが、 少なくとも btyacc と bison はそうではない。 また、GLR についていえば、 そもそもアルゴリズム上どうやったら Lexical Tie-in を扱えるのか分からない。 なお、zyacc は yacc 以上には進まないので関係ない。
まぁ、字句解析が進みすぎないようにするという手はあるかも知れないけれど、 なんでそこまで考えなきゃいけないのかという気はするわけで、 使う道具が間違っているんじゃないかと思う。
ならどうするのがいいかというと... 自分でやるなら、 「あの非終端記号からあのルールを除いたもの」 といった記述を展開する yacc のプリプロセッサを書くかな。
でも、そういった記述を受け付ける parser generator があってもおかしくないと思うのだが...
IgnoreClass を確認するのに DOM Inspector が便利であることに気がつく。
コマンドラインから直接起動できると便利かも、と思って調べてみて、 DOM Inspector に書いてあることを発見するが、うまくいかない。 普通の mozilla が起動してしまう。
なんとなく、yet another install.rb というか、そういうものを書く。
ところで、install.rb って何種類あるんだろう?
[latest]