この数日はプログラミングどころじゃなかったんで ほとんどマシンの電源を入れてませんでした。
今日からはしばらく暇なので、懸案をかたづけたいと思います。 まずは net/http かな。 次に比較的簡単な tdiarysearch のツッコミ検索をやっつける。 その次はその場にならないと決まらなそう。
Ripper はいつになるやらわかりません。 誰か続きを実装しませんか。 一番面倒なところは終わってるんだから、 あとはいちばん楽しいインターフェイス作りだけですよ。 ぼくにまかせてたら来年の夏休みとかになっちゃうかもしれませんよ。
(18:35)
激しく熱い変更を入れました。
さらに、これから PUT リクエストのボディに IO を使えるようにします。 こっちはさらに熱いぜ!
(02:03)
そういえば、昨日 (金曜) の夕方、 BitChannel に初荒らしが来ました。 ところがその 6 時間後にはどなたかが直してくださったようです。 ありがとうございます。
ちなみに、ぼくが気付いたのはさらに 12 時間後でした。 楽してるなあ。
(03:32)
さらに net/http をいろいろ変更した。
やっぱり require 'net/https' を必須にすることにした。 これなら OpenSSL がない環境では require が失敗してくれるのでわかりやすい。
コード例
require 'net/http' Net::HTTP.start('localhost') {|http| req = Net::HTTP::Post.new('/') File.open('data.txt') {|f| req.body_stream = f req.content_length = File.size(f.path) print http.request(req).body } }
POST に限らずなんでもいけます。
コード例
require 'net/http' Net::HTTP.start('i.loveruby.net') {|http| res = http.get('/d/') p res.get_fields['Set-Cookie'] #=> ["new=20040306123411; path=/d/; expires=Sun, 07-Mar-2004 05:52:38", "hoge=dxxxrag; path=/; expires=Sun, 07-Mar-2004 12:49:01"]
ようするに Set-Cookie 対策。
これでちょっと様子を見て、大丈夫そうなら正式採用とします。 1.8 はどうしよっかなあ。
(05:59)
ついにねんがんの version.h を更新したぞ!
あー、とつぜんロマサガやりたくなってきた。特に 3 が。 好きなのは 1 なんだけど長いので真面目にやるのはだるい。 2 は自由度が極端に減ってしまったのが気に食わない。 最初はキャットに助けてもらわなかったおかげでやたら難易度高くて酷いめにあったなあ。 要塞とか草原の移動戦艦を真正面から攻略しないといけなくなる。 3 は雰囲気がけっこう好きだったけど、あいかわらずストーリーが支離滅裂だったな。
そういえばロマサガ 3 には株取引みたいなのがあったような気がする。 なんだっけあれ。
そういえば半熟英雄みたいな戦闘シーンもあったような気がする。 謎だな 3。
うわー、まずい、本当にやりたくなってきた。 買ってこようかな。
(06:51)
http://ponx.s5.xrea.com/bibo/20040309.html#p02
ツッコミ入れようと思ったらエラーになってしまったので、 こちらに書いておきます。
Windows 上で動く Ruby それぞれの違いについてです。 あくまで「ぼくが理解した……」という頭書きつきで読んでほしいのですが、 まとめると次のようになります。
msvcrt というのは MS VC++ Runtime のことで、 ようするに libc みたいなもんです。 mswin32 ruby は VC++ でコンパイルして msvcrt とリンクした ruby。 mingw ruby は MinGW の gcc でコンパイルして msvcrt とリンクした ruby です。 だから mswin32 ruby と mingw ruby は拡張ライブラリを共有できます。
ついでに Cygwin 版というのは、 Cygwin の gcc でコンパイルして、 Cygwin DLL とリンクした ruby のことです。
ただし本質的なのはコンパイラではなく リンクしているライブラリのほうなので、 対応しているビルドスイートさえあれば Linux 上で Cygwin 用や msvcrt 用の ruby をクロスコンパイルすることもできます。
よーするに、問題は動くときの calling convention と ランタイムライブラリなんです。 アーキテクチャは同じ (i386) なんですから。
でもって bcc 版がよくわからんのですが、 あれもランタイムライブラリは msvcrt なんでしょうか? それとも独自 libc?
(追記) あー、とっくの昔にうささんの説明が出てた……。
(追記 2) 田村さんのところにも言及があった……。
(19:36)
結局中古で買ってしまった。1280 円で安かった。 スーファミ本体は当然のごとく動態保存されているので問題なし。 AC 電源なんてファミコンのをずっと使ってるんだけど、よく壊れないな。
(20:17)
うっわ、これはまたすごいな。構造体型フラグがのきなみ変わってる。 1 ビット空けたということは、1bit GC への布石と予測してみる結合テスト。
(02:10)
確定申告の副作用として 2003 年は本に 40 万以上費したことが明らかになったわけですが、 2004 年はまだ 1 万しか使っていません。 その 1 万で買ったのがこれ。
『Solaris デバイスドライバ』 佐島隆博著、オライリージャパン、2003
『4.4 BSD の設計と実装』 Marshall Kirk McKusick, Keith Bostic, Michael J. Karels, John S. Quarterman 著、 砂原秀樹監訳、七丈直弘訳、ASCII、2003
このラインナップを見ると、 どうも OS がマイブームらしいということがわかります。 ま、どうでもいいですけど。
ところで『Solarisデバイスドライバ』ですが、なかなか愉快な本です。 第一章でお約束の null デバイスを作ったかと思うと 第二章がいきなり Matrox Millennium II で、 しかもビデオカードとして使うのではなくてメモリとして使うらしい。
萌える〜。
で、第三章からが本番で、 ギガビットイーサネットアダプタ TC9020 のドライバを書きます。 ちゃんと使えるドライバを全部作ってくれるのが気持ちいい。 もちろんソースコードがビシバシと出てくるし、 350 ページ中の末尾 100 ページは全部ソースコードです (Makefile も付いてます)。
燃える〜。
世の中、萌え燃えだよ。
(20:02)
http://mput.dip.jp/mput/?date=20040314#p01
「タイムスタンプカウンタは Pentium と Alpha と PowerPC にある」 なんて言われてしまうと Alpha でも誰かがやらなければなるまい。 "Alpha Architecture Reference Manual" を見てみると なんとなくそれっぽい PCC (Process Cycle Counter) register というのを発見した。
下位 32 ビット (PCC_CNT) は CPU サイクル N ごとにインクリメントされるらしい。 N は 1 から 16 までの実装依存……てなんだよそりゃ。 PowerPC みたいにバスクロックでカウントされるのかなあ。
一方、上位 32 ビット (PCC_OFF) は OS 依存らしい。OS? でも「OFF」はたぶん「offset」の略だろうな。 普通に実装してあれば 64 ビット整数として読めるってことか。
あっ、それも書いてあった。 OpenVMS と Tru64UNIX はプロセスごとのタイムスライスを持つようだ。 マシン全体ではないのね。
PCC レジスタは RPCC (Read PCC) 命令で読めるらしい。 ふーむ。こんな感じでいいのかなあ。
#include <stdio.h> static unsigned long rpcc(void) { __asm__ volatile ( "rpcc $0\n" ); return; } #define PCC_CNT(pcc) ((pcc) & 0xffffffffL) #define PCC_OFF(pcc) ((pcc) >> 32) static void print_rpcc() { unsigned long pcc = rpcc(); printf("PCC = %016lx\n", pcc); printf("PCC_CNT = %08lx\n", PCC_CNT(pcc)); printf("PCC_OFF = %08lx\n", PCC_OFF(pcc)); }
これだと rpcc() の返り値が正しくないように見えるが、 Alpha では返り値を整数レジスタ 0 ($0) で返すので アセンブラレベルではうまくいく。と思う。 unsigned long を返す関数を定義してコンパイルしてみたら ほぼ同じコードになったのでたぶん大丈夫だろう。
この関数を使い 1 秒 sleep しつつ PCC を表示してみる。 できれば Tru64 でやりたかったんだけど、 まだ gcc を入れてないのでとりあえず NetBSD/Alpha だ。
aamine@asv800 % ./rpcc PCC = 3a7950a5579ad207 PCC_CNT = 579ad207 PCC_OFF = 3a7950a5 PCC = 309d4e756ba2cda0 PCC_CNT = 6ba2cda0 PCC_OFF = 309d4e75 PCC = 26a43e187fa3ce87 PCC_CNT = 7fa3ce87 PCC_OFF = 26a43e18 PCC = 1c8d622f93a4cb79 PCC_CNT = 93a4cb79 PCC_OFF = 1c8d622f PCC = 1258c7a0a7a5cd87 PCC_CNT = a7a5cd87 PCC_OFF = 1258c7a0
えっと、なんか PCC_OFF が変化しすぎ? なんだろうなこの値は。これは NetBSD カーネルも読まないとだめか。
つづく。
(18:01)
NetBSD のヘッダファイル alpha/alpha_cpu.h で、 alpha_rpcc() という直球な関数を発見した。
static __inline unsigned long alpha_rpcc(void) { unsigned long v0; __asm __volatile("rpcc %0" : "=r" (v0)); return (v0); }
こう書けばよかったのか。
(18:09)
一方 Tru64UNIX では、alpha/kintrinsics.h という 怪しげなヘッダファイルに rpcc() という関数の宣言を発見した。 しかし「k」intrinsics だけあってカーネルの内部関数だったらしい。
しかたがないので、まずダミー関数を書いておいて cc -S rpcc.c でアセンブリソースを生成し、return 77 に相当する部分を rpcc $0 に置き換えた。うまくいくかな。
~/c/test/rpcc % for i (a b c d e) { ./rpcc; sleep 1 } 5a0f27cda62505f6 410e81e0bf212645 286c7741d7c2c8d4 0fc9d1aff0642e68 f72717a20907be70
取れた。値の遷移には NetBSD と同じ傾向が見られる。 ますます謎だ。
(19:03)
今日 3/15 (月) の 19:30 ごろ、 i.loveruby.net が原因不明の過負荷状態に陥ったため一時マシンを停止しました。 いちおう直ったみたいですが、まだ妙に重いですね。やばいかなこれは。
(19:46)
ふと見るとホームディレクトリに cdr/ というディレクトリがあった。 「cdr? なんで Lisp?」と思ったが、 よくよく考えると CD-R を焼くディレクトリだった。
汚染されてるなあ。
(13:58)
激しいブランクののち製作を再開。 三ヶ月も空いてしまったか……。
もう何をやってたのかすっかり忘れてるな。 ああそうか、電源パターンの強化だった。 これ、本当にやらなきゃだめなのかなあ。 すっとばしても動いたりしないだろうか。 まあたぶん動いちゃうんだろうけど、 まんがいちだめだった場合に泣きそうだしなあ。 真面目にやるか。
しかしすぐ飽きる。回路図に出てこない線なので 赤ペンで塗りつぶせるわけでもなく、たいくつだ。 それでいてこれが結構むずかしい。 回路表面の一点にとっかかりなしで二本のリードをつけないといけないので、 こう、うまく二本をいっしょにまとめて……ああっ、外れた! 片方ずつ付けると、二本目を付けてるあいだに一本目が外れてしまうし。
片側やって飽きた。電源関係の残りを先にやるか。 だまだまを作って 5V と GND に直結する。 こっちは楽しい。
やる前は大変そうに見えて実は簡単なのが IC のハンダ付けだ。 テンポよく付けていけば足一本に一秒もかからないので、 IC 一個につき一分もあれば終わる。 IC に限らず、回路をいじってる限りは進行は早い。
一方めんどくさいのは何と言ってもリード線。 長さを決めて切って被覆をむくのがめんどくさくてしかたがない。 逆に言えば、回路を自分で焼いてしまうとめちゃくちゃ簡単そうだ。
ま、そんなわけで電源パターンの強化はめんどくさい。地道にやろう。
(15:33)
だめだ、地道にやるのは性に合わない。
1. 片側だけを長めにむいておき、芯線を机で押し込んでズラす。 一本につき剥くのが一回だけで済んでちょっと楽。
2. 二本いっぺんにカッターで剥く。
3. リード線を長めに切って片側だけ被覆を剥いておく。 使う直前に剥いてないほうを切って 1. を使って両側を出す。 いちいちリード線を切らずに一気にハンダ付けできるのでちょっと楽。
ああ、激しく車輪の再開発をしてる感じ。
ところで、ずっと思ってたんだけど、何で車輪なんだろうね?
(15:44)
情報ありがとうございます。 ウレタン線……このサイトで紹介されている UEW というやつですね。
http://elm-chan.org/docs/wire/wiring.html
おおっ、これは……楽そうだ! レジスタまわりの配線もこれなら余裕でいけるかも。
(16:26)
■ Yuya [信号線なら、ウレタン線を使うとか。]
ここ数日はやる気なくだらだらしてます。 TD4 の配線したり Alpha のファームウェアまわりの仕組みを調べたり。 その結果をまとめたのがこのへんのページ。
そういえば、その途中でクロックカウンタの使いかたも判明しました。 PCC_OFF (PCC の上位 32 ビット) と PCC_CNT (PCC の下位 32 ビット) を足すと目的の値が出るらしいです。 ただその値はプロセスごとのクロックカウントなので、 絶対時間を計測するのには使えない模様。 この仕様はファームウェア (正確には PALcode) レベルで決まっているので ユーザレベルから手を出すのは困難です、というか無理です。 カーネル内なら PALcode の管理してる領域に手を出せるのでどうにかなりそうです。
(16:13)
SKK じゃないと原稿が書けない人間としてひとこと言っておきたい!
なぜ SKK が好きかと言えば、変換単位が小さいからでしょうね。 確かに MS IME とか ATOK とかその他いろいろな IME は 長い文章を一気に変換するのは優秀です。 でも、逆に言えば文章が長くないとうまく変換できないわけですよ。 例えば文を一気に書いてから一部をちょっと手直しする場合、 結局文節や文字単位で変換することになる。
でもって、長い文章を書くときに重要なのはどっちだと思います? 文章を最初に入れるときか、後から追加修正するときか。 統計をとって調べたわけじゃありませんが、ぼくは後者だと思います。 だいたい追加修正のほうが時間がかかるし、たくさんやるんです。 だから、効率を考えるなら追加修正機能にこそ注力しないといけません。 その点において現在の主流である連文節変換 IME は全く能力不足です。
(16:35)
ようやく Tru64UNIX のホストにも ssh でつながるようになった。 かねがね思ってたんだが、ssh の設定は OS ごとに差がありすぎだ。 public key の設定 (ログインされる側) だけでもこんなにある。
頼むから、こんなところで多様性を追求するのはやめてくれ。
(19:33)
■ shugo [では一文字単位で入力できるt-codeを、とか。]
■
青木 [t-code にも興味はあるんですが、
学習コストが大きすぎるのがちょっと……。]
■ ただただし [若いうちがチャンスだわよ >T-code]
■
t15u [vi+T-Codeは快感です。2週間くらいかけて気合でT-Codeの
ひらがな全部覚えれば後はまぜ書き変換使ってジョジョに
なんとかなります。]
■
kawaji [tmail の時代が来る! のかな?
http://www.icann.org/tlds/stld-apps-19mar04/mail.htm]
■ 青木 [もう年なので t-code は覚えられませんと言ってみる]
■ 青木 [商標とっといたら儲けられたのかなあ > .tmail]
土曜の記録を火曜に書くってのはいかがなものか。 とりあえず、全般的な記録は RWiki からどうぞ。
今回は対象範囲が短いわりに興味深い論点が多くありました。
個人的に一番面白かったのは $SAFE の話かな。 あのあともうちょい考えたんですが、確かに今の $SAFE の仕様は変です。 すんごく単純に考えると、 $SAFE=1 では tainted なオブジェクトは多いほどよいはずです。 一方 $SAFE=4 では tainted なオブジェクトは少ないほどよいはずです。 これは明らかに矛盾している。
ちなみに $SAFE=4 の理想的な姿はどうかと言うと、 (今の仕様で言う) tainted オブジェクトがない状態から始めて 公開してもよいオブジェクトだけを taint し、$SAFE=4 に入るのがベストでしょう。
それからまた別の話題で、正規表現の名前付きキャプチャ。 いまは括弧にマッチした部分は $1, $2... のように番号でしか取れないけど、 それを名前で取りたいという話です。 akr さんはローカル変数に代入されるのがベストだという意見でした。 こんな感じかな?
if /xxx(?k=foo:....)xxx(?k=bar:....)/ =~ str p foo # マッチすると代入されている p bar end
正規表現中の文法は議論を覚えてないので今でっちあげました。 なお、この機能は正規表現リテラルを直接書いた場合だけ働き、 埋め込み式 #{....} がある場合も機能しません。
一方、ぼくの意見はこんなんです。 あくまで現在の延長線上でしかない仕様ですね。
if m = /xxx(?k=foo:....)xxx(?k=bar:....)/.match(str) foo, bar = *m.select(:foo, :bar) p foo p bar end
あっ、そうだ、Binding を明示的に渡すというのはどうだろう!
if /xxx(?k=foo:....)xxx(?k=bar:....)/.match(str, binding()) p foo p bar end
先生、とても組み込みライブラリの仕様には見えません!
ああ、あとそれから、POOS (Plain Old Open Source) っていうネタもあったなあ。
酒井さんから「代数」について学ぶ会。
さらにそのあと、終電のなくなった酒井さんにつきあって 笹田さんの研究室にお邪魔してきました。 メンバーは笹田さん・酒井さん・shelarcy さん・青木。
いやあ……
いろんな意味で濃かった。
(21:11)
■ こさこ [正規表現リテラルの場合だけ機能するということで満足するかしないか、という選択の問題だと思います。]
■ shiro [飛び入りしますが、正規表現リテラルを「プログラムコードの一部」とみるか、組み込みであっても外部のオブジェクトと見るかの差とも言えるかも。正規表現リテラルがfirst class objectとして扱われていないなら、わざわざ正規表現オブジェクトを作成するまでもなく、正規表現のマッチコードを自体を周囲のコードのコンパイル結果に埋め込んでしまう、という選択肢が考えられるわけで。そういう文脈で考えればレキシカルにマッチ結果が束縛されるのは自然ですね。]
■
akr [読書会では Regexp は、String を受け取ってマッチ可能かどうかを真偽値を返しつつ、
副作用としてキャプチャした部分文字列をローカル変数に代入するクロージャである、
という考え方を述べました。
(もちろんマッチオブジェクトを $~ に代入すると言う副作用もあっていいわけです)
言いませんでしたが、この考え方を押し進めると、
Regexp A の中に #{} で Regexp B を埋め込むのは、
特殊な関数呼び出しであって、そうだとすれば
B 内のキャプチャは B がリテラルとして記述されたスコープにおけるローカル変数への代入になるのが自然であるとも考えられます。]
■
shiro [Schemer的には、副作用よりは束縛の導入にしたくなります。こんな感じ:
(with-regexp #/(?k=foo:...)(?k=bar:...)/
... ;; ここでfoo, barが束縛されている
)
ただ、これだと別の箇所で出てきたregexp Bを埋め込むってところのセマンティクスが難しいかなあ。
いずれにせよ、これはおもしろそうなんで、ちょっといじくってみようと思います。]
■
akr [問題は first class な pattern はどうあるべきかってところですかね。
なんか、いかにも論文がありそうな感じ。]
with-regex は Ruby 的にはブロックでしょうね。
/xxx(?<var>.....)xxx/.if_match(str) { p var }
こっちのほうが binding よりはマシっぽい。
でも else が書けないのは嫌だな。かなり無理矢理だが、 マッチしなかったらメソッドが nil を返すってことにして……
/xxx(?<var>.....)xxx/.if_match(str) { p var } or return nil
うわ、読みづらっ! これはだめだー。
http://cvs.m17n.org/~akr/diary/d2004_03.html#a2004_03_24_1
名前付き括弧の利点は、括弧の順番が変わっても大丈夫というところだと思います。 そういう利点があるんだから、多少コードが長くなってもいいんじゃないでしょうか。 メソッドを呼ぶと知らないうちにローカル変数に代入されてるってのは やっぱり想像しにくいですよう。
(02:46)
■
kjana [/(?<s1>foo).*(?<s2>bar).*/.match(string) {|m| p m[:s1]} とか.
MatchData#[] が Symbol を受け付けるようにするだけ.微妙....
if m = regexp.match(string)
puts m[:foo]
else
puts "nothing matched."
end
ってな書き方はできる.Regexp の埋め込み? 気にしちゃいけない :-P]
■
akr [$~[] に名前を使うことに関しては、[ruby-dev:19785] で、まつもとさんが、
「1.9がはじまったら私の方でやります。ちょっと待っててね。」と述べています。
したがって、(ちょっとというのがいつのことかはともかくとして)それはそうなるはずです。
ただ、それだけだと $1 より短くはならないと思うんですよね。]
ヤフオクに凄いものガっ!
http://page.auctions.yahoo.co.jp/jp/auction/65997681
AlphaServer ES40 だよー。21264 が 4 発。 いいなあっ。
どうも、春に Alpha が出る確率が高いような気がする。 やっぱこの時期に放出されんのかね。
(07:53)
とりあえずフォルネウス (影) をぬっころしておいた。 やっぱ四魔貴族戦の音楽はかっこいいなあ。影も実体も。
それにしても最初にやったのが 8 年前だけあってすっかり忘れてる。 「ぬれてにあわ ぬれてにあわ」とか「きょ・う・じゅ」とか、 本筋と全然関係ないキーワードは覚えてるんだけど。
(10:15)
ホームを歩きながら Wiki で日本語ページ名を扱う方法を考えていたら すごいアイデアを思いつきますた!
「t-code エンコーディング」
[[ ]] の中に t-code でページ名 (もちろん日本語) を書いておくと 変換後の文字列がページキャプションになる。 変換前の文字列が URL になる。
(15:11)
http://cvs.m17n.org/~akr/diary/d2004_03.html#a2004_03_25_1
簡潔であり、かつ変更に強い記法が一番よいという点は同意します。 しかし、まず他のメソッド内でローカル変数に代入させるという操作自体が、 ぼくは Ruby 的でないと思うのです。 つまり、ローカル変数に代入させるということ自体をまずあきらめている。 そしてローカル変数がだめなら他の変数系は論外だし、 そうなるとどうしてもメソッド呼び出しくらいはやらなきゃだめでしょう。 それじゃどうせ m[:foo] と比べてたいして短くならないんだから これ以上短くするのは潔くあきらめたほうがよいと思います。 以上が前回の発言の背景です。
また他に akr さんの案で弱いと思うのは、 リテラルとして書かれた場合にのみ働くというところです。 この自動代入機能 (と仮に呼ぶ) は、 確かに変化に強い記法の中では最も簡潔であって、プログラマに好まれます。 従ってプログラマはできることならそちらを使いたいので、 正規表現を複数のパーツに分割したり定数に入れたりするのをやめてしまうかもしれません。 これはより広い視点で見たときにコードの質を落とす圧力となるのではないでしょうか。
と、ここまで書いたところで全然違う活用案を思いつきました。 MatchData の特異メソッドにするってのはどうだろう。
m = /xxx(?<foo>....)xxx/.match(str) p m.foo
(16:18)
t-code と同軸のネタで、 ローマ字入力しておくとひらがなに変わるというのもあります。 別にカナ打ちでもいいですが。
さらに、SKK 風にシフトを入れて打つと WikiName っぽくなるので それを適当に変換するという無理無理なネタも考えました。 submit すると変換候補をリストアップして返してくるので、 そこから選びます。
無駄すぎる。
(16:58)
マジにネタレスというのはどうだろ。 「マジパンにレタス」と少し似ている。
どうでもいいか……
唐突に話を始めます。
現在 BitChannel は日本語ページ名を認めていません。 BracketName はあるんですが、[a-zA-Z0-9] 以外が入ってるとリンクになりません。 日本語ページ名のいい実装を思いついてから許可しようと考えているからです。
では、どんな条件を満たすのが (BitChannel 的に) いい実装でしょうか。 少なくとも以下の条件は必要だと考えています。
えらい厳しい要求にも見えますが、 WikiName だけの Wiki ではこの条件がすべて満たされています。 したがって日本語を入れる際にも この条件は満たしたまま導入しなければ我々の負けです (そういう問題か?)
なお WikiName の特徴としてもう一つ挙げられるのが、 文字を追加するのではなく、文字を削ることで意味を持たせる点です。 できることならこの特徴もエミュレートしたかったんですが、 あまりにも無理そうだったのでやめました。 人間、限度はわきまえないといかん。
まず Wiki ソース上でリンクを作成する方法について考える。
[1] BracketName。[[ ]] でくくって指定する。 ソースと表示画面で見ためが違うのがちょっと嬉しくない。 またどんな文字列でもリンクにできてしまうのは両刃の刃。
[2] 1 の変形で、””や「」でくくる。 こちらの場合は ””などの区切り文字自体も表示されることが多いようだ。 その点で 1 よりは多少よい。しかし見ためがあまり嬉しくない。
[3] はてなキーワード方式。 既存の日本語ページ名と一致する部分文字列が自動的にそのページへのリンクになる。 この方式は特殊な工夫を併用しないかぎり ページの作成に「新規作成」メニューが必要になるので許容できない。
[4] スペースで区切られた部分文字列が「××の××」であった場合、それをリンクとする。 「××」は漢字・カタカナ・ひらがなのいずれかでなければならない。 行頭に置くと pre ブロックの文法と衝突するのが問題。 マッチしすぎそうなのが問題。 直感的でないのが問題。 ルールが独特すぎるのも問題。
[5] XXXXX-no-XXXXX をリンクとする。 これをひらがなに変換してページ名とする。 漢字は使えない。
[6] t-cod(ry
[7] 任意桁を縦読みしたときに「リンク」ってなってたらリンク
[8] 「→」を前にくっつける。本質的には BracketName とたいして違わない。 (SKK だと zl で「→」が出せることに頼って他の IME ユーザを度外視した作戦)
[9] 一文字だけの行が三行以上続いてたら全部つなげてリンク
[10] ある行が「××の××」という形式だったらリンク
なんかあれを思い出すね、傘の使い道をたくさん考えなさいってやつ。
次に、ページ名を URL にマッピングする方式について考える。
[1] ページタイトル文字列をそのまま URL エンコードして生成する。 最も一般的だが、この方式は URL を意味不明かつ % まみれにするので許容できない。 また URL が内部文字コードに依存する点は明らかに問題である。
[2] ID 方式。システム側がページに ID を割り振り、URL ではそちらを使う。 この方式は URL が意味不明になるので許容できない。
[3] 最初にページを作るときにアルファベット名を指定させ、URL ではそれを使う。 この方式では最適な URL を生成できるが、 ページ作成の手間が多少増えるのが問題である。
[4] ページ名を kakasi にかけて無理矢理アルファベットに変換する。 この方式では 3 におけるページ作成の手間を削減できるが、 必ずしも読みやすいとは言えない。 またインストールの手間も増える。
[5] だから t-cod(ry
現実的なのは BracketName と生成時の別名指定か。 「ソース上と表示画面上の見ためが同じ」 というポリシーだけ捨てれば採用できる。 でも、本当にそれでいいのかなあ。おもしろくないなあ。
おもしろさだけで言えば「××の××」形式だろう。 「××の××」ってのは、なーんとなく 「形容詞 + 名詞」のページが多いかと思って選んだんだけど、 ちゃんと統計をとって決めれば意外と使えるかもしれない。
それにつけても眠い。 眠いからこんなはっちゃけたないようがないようなないようになってるわけか。
(19:33)
そういえば、メインバックエンドに CVS がいる Wiki で MonaWiki というのがあるんですね。例によって YukiWiki 系だそうです。
http://www.hyuki.com/yukiwiki/wiki.cgi?MonaWiki
(19:42)
■
ねたに混じれ酢 [それで、そのURLからはページ名がすぐに思い浮かぶのですか?
>t-code使いの方々]
■ shiro [「リテラルとして書かれた場合のみ」:処理系の立場からすると、動的なregexpはevalするコード、リテラルは地のコードってことなんで不自然じゃないですね。むしろregexpを言語外のエンティティとして扱ってきた歴史が、両者の混在に対してなんか落ち着かない感じを覚える理由なんではないかと(自分では)思います。]
■
ねた(に混じれ酢)\\1 [(少なくとも私は)思い浮かばないですね。謎の文字列にしか見えません。
またその文字列のとおりにキーボード上で指を動かしても、脳内デコードはできません。]
■
t15u [漢字->指の動き○、漢字->謎の文字列×、
指の動き->漢字×、謎の文字列->漢字×
私の場合もこうです。
わかりにくさを利用してパスワードをT-Codeでいれることがあります。]
■
青木 [そうかあ、t-code エンコーディングはだめですか。
とすると流用できそうなのは、単に圧縮度の高いエンコード手段、
くらいでしょうか。]
http://cvs.m17n.org/~akr/diary/d2004_03.html#a2004_03_26_1
そうか、MatchData のメソッドにマップする案は既に出てたんですね。
ちなみに「$ 変数ステ」の流れに思いきり逆行して $~name てのはどうでしょうか。 だめですね、はい。
さて、「Ruby 的でない」だけではわからんと言われたので どこが Ruby 的でないと思うか説明します。 Ruby 的でないと思ったのは、 「正規表現をクロージャと考えれば」というところです。 現在 Ruby でクロージャを作るにはブロックを使うか、 メソッドやクラスを定義するか eval するしかありません。 つまり eval 以外は「{....}」か「予約語〜end」です。 正規表現の文法はこのどちらでもないので クロージャ (を作る文法だ) とは認めたくありません。 また eval に似せるなら dynamic scope でないといけません。
だから逆に言うえば「{....}」か「予約語〜end」ならクロージャでもいいです。 ただし %r{....} なんてのは嘘くさいので嫌です。
またそこは我慢するとしても、 その場合は /regexp/ の「/」と「/」の間が文法的なスコープに なるのではないでしょうか。例えば /xxx(?<a=>....)xxx/ は、
lambda { ....; a = xxx; .... }
であって、Ruby ルールでは a は外からは見えないはずです。 もっとも
a = nil re = lambda { ....; a = xxx; .... } p a
であれば納得できますが、この場合、 a = nil は正規表現よりも前になければいけないと思います。 つまり以下のように書くのなら納得できます。
# パターン1 a = nil if /xxx(?<a=>....)xxx/ =~ str p a end # パターン2 a = nil re = /xxx(?<a=>....)xxx/ .... if re =~ str p a end
一方、yacc のように部分パターンごとに アクションが指定できるというのはアリだと感じます。 アクションブロックの文法がブロックに似ていれば違和感を感じません。 例えば
/xxx(??.....){|name| p name }xxxx/ =~ str
とか……。
あ、でもこの場合はそもそも名前付きとは言えませんね。 しかもブロック内なので代入してもブロックローカル。 ブロックが複数あるときに情報を渡すのがめんどくさい。 バックトラックしたらどうなるのか混乱する。 などなど、いろいろな罠がありそうです。
あああああ! そうか! 正規表現一つで済まそうとするからいけないんだ! 正規表現パターンとアクションを組にできるようにして、 それを合成して作ればいい。
pat1 = /xxx/ {|tok| p str } pat2 = /yyy/ {|tok| p str } re = /aaa#{pat1}aaa#{pat2}aaa/
awk だな。awk すぎる。#{...} を使って直接埋め込めばテンポラリ変数も不要か。
re = /aaa#{ /xxx/ {|str| p str } }aaa#{ /yyy/ {|str| p str } }aaa/
むむ……意外といけそうな気がしてきた。
うーん。 でも、こういうアクションみたいのは共有して嬉しいことはなさそうだから、 ブロックは正規表現にではなくマッチする場所に所属するべきか。
/re/ { .... } がパターンとブロックの組を新しく作って返せばいいのかな。 ついでに Regexp#on_match を作って同様の操作ができれば ブロックだけオーバーライドできる。
WikiName = /([A-Z][a-z0-9]+){2,}/ def compile(src) syntax = / #{ WikiName.on_match {|str| .... } } | #{ URI.regexp(%w(http ftp)).on_match {|str| .... } } | #{ /[<>&"]/ {|c| escape_html(c) } } /x src.gsub(syntax) {....} # ここで破綻 end
だめだ、使えない。 このセンはあきらめよう。
(04:29)
ちょっと様子を見て 0.2 を出しますか。
ちなみにコメントボックスと日本語ページ名を実装したら 1.0 にします。
(06:02)
もういっこ考えついた。 単語の「日本語 → アルファベット」の組をたくさん登録しておき、 登録単語 2 or 3 個以上を組み合わせた場合のみページ名となる。 登録した単語のアルファベット名を連結して URL を作る。
あらかじめ SKK 辞書あたりから単語をひっぱっておけば それなりの範囲をカバーできそうだが、 どう考えても実用には足りないので変換時に登録を許すことにする。 [[ ]] でくくると強制リンクとなるが、 この内容が登録済み単語の組み合わせに分解できない場合は 分解できるまで何度でも新しい単語を登録させる。
疑問
利点
欠点
(12:19)
■
id派 [http://www.kanzaki.com/docs/Style/URI.html
のように長い目で見てURLに文書のタイトルを入れるべきではないという意見もあります]
■
非ID派 [本当に「件名を入れるべきではない」と書いてありますか?
(たしかに、「件名による分類は避けるべきだ」という記述はあります。)]
■ id派 [『最初はたいていうまく行くように見えるのに、あっという間に違ってきます。』と書いてあります。]
■
青木 [元々の文章が曖昧なのがいかんと思いますが、これは
やっぱり分類 (ディレクトリ) に関する話でしょう。
その証拠として、直後に「よい」 URL の例として
".../chairs" が提示されています。一切名前を使う
べきでないのなら、識別子 chairs は不適切です。
また、ちょっと方向性の違う話ですが、そもそも URL が
変わって困るのは、自分の欲しい情報にたどりつけなく
なるからです。しかし Wiki においてはページ名を変え
たら新しいページへのリンクを作るのが一般的ですから、
被害は最小限にとどめられると思います。]
■
青木 [(補足) プログラムで自動化する場合は例外ですが、
現実的に見て HTML と HTTP を使ったレガシーシステムに
そこまで厳密性を期待するのは間違いだと思います。]
sprintf がらみの酷いバグを指摘されたので修正。
POPS はどうしようかなあ。 これ以上 start の引数を増やすのは嫌だから、 net/https みたく new してセットするようにしようかな。
(14:41)
今日はひたすら実装の日なのです。
1. mod_ruby だと $0 が false になっている
Apache.request.filename で代用。
2. fork すると直後に SEGV
謎だ。例えば次のようなプログラムを実行すると、
# fork.rbx def log(msg) File.open('/tmp/log', 'a') {|f| f.puts msg } end log "pid=#{$$}: start" pid = Process.fork { log "pid=#{$$}: (child) fork OK" exit 0 } log "pid=#{$$}: (parent) child=#{pid}" dummy, status = Process.waitpid2(pid) log "pid=#{$$}: waitpid=#{status.inspect}" print "HTTP/1.1 200 OK\r\n" print "Content-Type: text/plain\r\n" print "Content-Length: 3\r\n\r\nOK\n" log "pid=#{$$}: program exit"
ログがこうなって、SEGV で落ちているらしいことがわかる。
pid=23072: start pid=23072: (parent) child=23079 pid=23072: waitpid=#<Process::Status: pid=23079,signaled(SIGSEGV=11)> pid=23072: program exit
なお環境は以下の通り。
(21:47)
(追記) Ruby が古いだけだった。情けない。
やっぱりいろいろ間違っていた。
CGI のときは suexec していたのでレポジトリが 一般ユーザ所有になってたのだが、 mod_ruby だと httpd 権限なのでロックできなくて落ちると。
これで一通り通るようになったんではなかろうか。
(22:57)
書き忘れてたけど他にもいろいろ入れました。
何気にでかい変更だったりする。
一連の変更が落ち着いたらリリースしますので、 それまでは以下のあたりを参照して CVS から取ってください。
(23:02)
(00:14)
結論から言うとソケットを受け取るのはやりません。
まず HTTP の場合、 HTTP 1.1 ではホスト名が必要になるので意味がありません。
POP のほうは、クラスでプロトコルを分岐するのはやめたいので採用しません。 クラスで分岐する方法だとほとんどハードコーディングになってしまうんで。
あと、APOP の使えるサーバだと無差別に APOP スタンプを渡してくるので 中田さんパッチの後半はまずいです。
(00:37)
思いついてしまったヤバ気な機能たち
更新されるそばからサーバープッシュで diff をたれながす。 Wiki における tail -f
限定 drb。 BitChannel に存在する便利そうな Ruby オブジェクトを 無造作に Marshal して返してくるサービス。 tDiary のプラグインから使ったりするといいことがあるらしい。 問題は Ruby のバージョンが違うと泣くことと、 あんまりおもしろいオブジェクトがないことか。 うーん。
(04:38)
■
なかだ [そもそもAPOPってinitializeのときに分かってないとダメなもんですか。
こういうのを考えてるんですけど。
http://nokada.jin.gr.jp/ruby/pops.diff
むしろNet::Protocol(のサブクラス)はホスト名とか受け取らずに、
オープンされたIOを受け取るようにしたほうがいいんじゃないかとか。]
■
だて [> Ruby が古いだけだった。情けない。
これって 1.9.0-20040316 でも古いってことですか?]
■
青木 [そうです。3/27 バージョンまで上げないとだめでした。
1.8.1 は試してません。]
■ 青木 [1.8.1 もだめでした。(mod_ruby は同じく 1.0 系 HEAD)]
■
だて [3/27 版で mod_ruby 下で動きました。ありがとうございました。
ついでに esehttpd で試したところ、cgi_url が "(eval)" になります。
Ruby 組み込みだと $0 が (eval) になるようです。
REQUEST_URI や SCRIPT_NAME でも参照するしかないですかね。。。]
■ 青木 [なるほど。それはバグですね。直します。]
Wiki みたく人気のあるテーマだと反応が大きいですね。 referer 見てるだけで勝手に情報が集まってくるのでとても便利です。 細かくは寝て起きてから反応するとして最後に言っておきたいのは、 RandomNote がすごく面白げだということだっ。
『結城浩のWiki入門』 で BitChannel を紹介していただきました。 のみならず、本をいただいてしまいました。
これはせめてレビューでもして売り上げに貢献せねばなるまいと思い 気合い入れて読み始めたのですがさすがに眠いのでこれも明日にします……すんまそん。
(05:33)
やばいくらいネタばっかり思いつきますな。
「古きよき日本の秩序ルール」
ページ名は五七五でなければならない。 オプションとして七七をつけてもよい。
(15:17)
■
だて [WikiName の日本語版は何かってことですよね。
仮名を区切り文字にして、四字熟語なんてどうでしょう。]
■
青木 [それは、「四字熟語 + かな + 四字熟語」ですか?
それとも四字熟語の途中にかなが入る? (ってのはありえないか)]
■ ささだ [【.+?】.+?【.+?】 でマッチしたら、とか。]
■
だて [漢字以外で切れば良いのでパースが比較的楽ってだけの話です。
熟語?だけの行があったらページ名とか。
例えばこの日の日記だと、段落タイトルと「古きよき日本の秩序ルール」が該当。]
■ ささだ [シンプルに半角カナだったら、とか。]
■ 青木 [問答無用で却下 ^^;; > 半角カナ]
そういうわけでレビューです。 けっきょく発売日になってしまったか。
『結城浩のWiki入門』
結城浩著、B5 変形 224 ページ、インプレス、2004
サポートサイト: http://www.hyuki.com/wb/index.html
特定の組織やコミュニティで情報を共有する場が欲しい人。 個人的なメモ書きやデータベースを作るシステムが欲しい人。 手軽なサイト構築ツールが欲しい人。 あと、WikiWay が厚すぎて読む気にならないけど Wiki には興味があるという人にもお勧め。
すでに WikiWay を読んだ人は買う必要なし。
WikiWay のおいしいところだけ選んで教えてくれる本。 日本向けの細かいローカライズがされているのもよい。
なんでもそうだけども、 道具が役に立つにはまず目的がないといけない。 Wiki で言えば目的は 「資料をみんなでまとめたい」とか 「文章をレビューしてほしい」とか 「サイト更新の手間を減らしたい」とかであって、 「Wiki を使いたい」ではないはずだ。
そういう意味では、「Wiki」と題名に入れてしまった時点で、 本来その本を読んで役に立たせられる人よりも読者層を せばめているわけで、ある意味すでに負けている。 しかも Wiki の場合は元々の定義が緩いこともあってか、 ツールが異様に広い目的範囲をカバー「してしまう」。 それこそ個人用メモ書きから超巨大コミュニティまで。 ツールと目的が一対一であれば何に使うかなんて迷わなくて済むが、 Wiki はその正反対だ。 だから、Wiki が具体的に何に使えるかが書いてあるのは Wiki 初心者 (この本が対象とする読者) にとっては 非常に重要なことだと思う。
その点から言って、この本はよくできている。 まず最初に Wiki の仕組みが簡単に説明されて、 次に具体的な目的が来る。 でもって 4 章になってやっとインストールになる。 これは Wiki 初心者向けの構成として最適であると思う。 端的に言うと、良書。
最後に章ごとの内容を紹介しておきます。
会社でプロジェクトの進捗を管理したり 作業日誌をつけるというシナリオのもと、 Wiki の典型的な使われかたを紹介していく。 結城さんの著書の例にもれず進行がおだやかで、 情報が多すぎないところに好感が持てる。
Wiki の使用例が具体的にいろいろ出ている。 もしかするとこの本で一番重要かもしれない章。 Wiki に向いている作業だけでなく、 「Wikiに向かない作業」もちゃんと挙げてくれるところがよい。
YukiWiki で稼働しているサイトをブラウズ・編集する方法を紹介する。 やったら薄い章だが、この章は薄ければ薄いほどよいと思う。 ただ使うだけのためにえんえん長い説明が必要なようではやる気も失せる。
Windows XP でのインストール。略。
一般的な使いかたと文法の話。略。
カスタマイズと聞いて一瞬 ソースコードをガリガリ書き換えるのかと思ったけど、 さすがにそんなことはなかった。 リソースの変更とか CSS の編集とかの話をする。
Wiki を実際に運用するうえで気をつけることとか、 指針が書いてある。これも重要な章だな。 「リファクタリング」「小人さん」など、 比較的プログラマよりの言葉をちゃんと使ってもらえるのは なんとなく嬉しい。
ところでそのリファクタリングについて、 p.185 に以下のような文がある。
「ページの目的にもよりますが、 いくつかのコメントで議論が決着したり、 事実関係が確認された後は、 コメント部分は削除してしまい、 結果だけを要点としてまとめてしまうのも一法です」
このような場合に最も問題になるのは、 「人の書いたものを消すのはためらわれる」 という心理的な壁ではないだろうか。 この障壁に対する一つの解が、バージョン管理システムを使うことだと思う。 バージョン管理システムが入っている Wiki では過去の内容がすべて残るから、 いつでも元の内容を見られるし、復活もできる。 だから完全に消してしまうよりもずっと気軽に編集できるはずだ (と、さりげなく BitChannel に有利な発言を混ぜておく)。
タイトル通りの内容。拡張技術を紹介している。
「アグリゲートする」って一般的かなあ?
なぜプラグインの話がここに入っているのかわからない。 分類的には第 6 章あたりに入るものじゃないのかな。
む、最後に「Wiki を作る 10 のポイント」 なんてものがある! これは答えずにはいられないな。
開発言語は Ruby。 プラットフォームは Ruby が動くところはほとんどだけど、 比較的マシンパワーが潤沢にあることを前提としている。
(めんどくさいので) 深いことは考えない。誰でも書け!
可能な限り厳選したブロック構造と、ハイパーリンクのみ使う。
WikiName はそのまま採用した。 日本語ページ名はできるだけ使いたいけど、システムはまだ考え中。
できるだけ小さくフラットな構造のページを密なリンクで結合する。
重視しない。
バージョン管理は必須。 別に CVS にこだわっているわけではないが現時点で CVS 以上に適当なシステムはないと思う。
とりあえず HTML 動的生成だけだけども、RSS には対応したい。 気が向いたら PDF 出力に対応してみるのもいいかもしんない。
ハイパーリンクがあれば十分かなあと。 あ、RSS はこっちに入るのか。
これは衝突する話なのかなあ。 まあ、WikiFarm は導入するつもり。
(20:38)
圏外からのひとこと効果でリファラが爆発してるなあ。
それはともあれ、必死こいて自転車をこいでいたら さらに別のアイデアを思いついたぜ!
「麻雀ルール」
大三元: 漢字 3 文字 + ひらがな 3 文字 + カタカナ 3 文字
字一色: 漢字 9 文字
四暗刻: 同一文字種 3 文字 × 4
七対子: 同一文字種 2 文字 × 7
まあ、よくよく考えると役になってるのか怪しいけど、 どうせ元から怪しいんだから厳密に考えちゃいかん。 どうせなら大型の役で名付けたほうが派手だからいいのだ。
国士無双とか天和は難しい。 というか、順序の組とか副作用 (e.g. ツモ) に頼った役だとエミュレートしても使いようがないから、 同一牌の役しかないわけだな。
役ごとに CSS class が変わる?
点数計算もすべきだろうか。 ページごととサイトごとで。
なんだかこれはもう実装するしかないって気になってきた! 定石から行くと名前は bit雀nel だろうな。
一つのしくみで五七五もカバーできそうだが、 ひらがなだけにするといろいろ問題がありそうだ。
(20:45)
Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved.
■ よんひゃん [あおきさん、はじめまして。tdiarysearch についてなのですが、下記のような状況で動きません。
http://www.yhlee.org/diary/?date=20040307#p01
tdiarygrep を試してみたらちゃんと動いたので、とりあえずは問題ないのですが、tdiarysearch はいずれツッコミ検索にも対応されるということで、できればこちらが使いたいです。お時間のあるときにヒントをいただければありがたいです。]
■ ま2 [ロマサガ3は,お金儲けゲームみたいのがありましたね。私は2が一番好きです。1はバランスメチャクチャだけど人を引きつける魔力みたいのがありました。2は面白くなった分破天荒なところが減って,3以降(サガ・フロとか)とんでもゲーになりました。]
■ あづみ [株取引っちゅーか、目の前に金を積んで「うちの傘下に入らんか
ゴラァ!」と次々店を買収していくやつですな。
技を覚える瞬間の「ぴこーん」も好きでしたが、買収していって
新しいグループが発生する瞬間の「ぴん!」も好きでした。
ミニゲームはいっぱい遊んだ記憶あるけど、最後までクリアした
記憶が一度しかない^^]
■ あおき [そうかそうか、トレードでした。
「クラウディウスを知る者来たれ!」だと
百万単位でガスガス出してくれるのが気持ちいいやつ。
なんだかんだ言いつつもロマサガ 2 もやりまくったもの
です。やっぱりスーファミ時代のゲームがやりたいなあ。
もう年か……。]
■ よんひゃん [先日は、ていねいに対応していただきありがとうございました。
お礼が遅れてすみません。
自分でも少しずつ勉強していこうと思います。
これからも、どうぞよろしくお願いします。]