2006/02/28

ひきつづき職場のPCの入れ替え。

弊社では、クライアントマシンのIPアドレスはDHCPで割り当てられている。この更新の頻度がけっこう高く、今日はちょっと固定的に同じ番号を使用したかったものだから、適当に空いてそうな番号を設定してみるという暴挙を犯してしまった。Windowsでは、固定的に割り当てようとしたIPアドレスがネットワークで既に使用されていると、強引に設定はされるものの警告が出る。おそらく、設定しようとしているIPアドレスを求めるARP要求をブロードキャストして応答を確かめているんだろうけど、とにかく警告が出ないアドレスは空いてるってことでしょ? ←これが思い込みであることがすぐに判明する

何がおこったかというと、最終的に警告なく設定できたIPアドレスが、Linux か何かが動いているマシンの固定IPアドレスと見事にバッティングして、相手をハングさせてしまった(おそらくNICが停止してリモートアクセスできなくなった)。管理者の S さん、ごめんなさい。本当にごめんなさい。

今回、相手のマシンは NIC の停止にいたったぽいけれど、ネットワーク上に同じ IP アドレスのマシンが存在してしまった場合(i.e. 自分のIPと同じ送信元IPを持つARPパケットを受信した場合)の挙動は、実装に依存して多種多用らしい。なかには気にせず通信を続ける実装もあるらしく、そんな場合は一部のパケットが別のマシンに取られてしまうことになる。ある種の実装で重複する IP アドレスを検出した場合に NIC を停止するのは、そのようなセキュリティ上のリスクを避けるためなのかもしれない。でも、ルータのような装置が NIC 停止型の実装だったら、かえって容易にサービス停止攻撃をまねきかねないよな。

こういう知識については、あまり知る機会がなかったりする。そんな話題にもしっかり触れている『基礎からわかるTCP/IP ネットワーク実験プログラミング第2版』は 2400 円。ぜひ ;)

『基礎からわかるTCP/IP ネットワーク実験プログラミング第2版』
http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=4-274-06584-7
会社のPCのリース替え。自分のだけなら楽なんだけど。

Windows XP なので、なにはなくても Cygwin をいれなければならない。Cygwin のターミナルはぶっちゃけWindowsのコマンドプロンプトでいらいらするので、Cygterm を入れてターミナルを変えなければならない。ところが、Cygwin をフルインストールしたせいか、Cygterm のコンパイル中に、gccで「_WinMainCRTStartup が multiple definition」とかいうエラーが出てとまってしまう。
とりあえず、Makefile に gcc に与えるオプションとして「-Xlinker --allow-multiple-definition」を追加すればコンパイルできることはわかったものの、これでよかったのだろうか? これはつまり、せっかく新しい PC なのでできるだけ全てのインストールをクリーンに行いたいという病気です。

2006/02/22

Amazonで先行予約開始になったもよう。書店でも、はやいところは25日には並びます。

Amazon.co.jp『RailsによるアジャイルWebアプリケーション開発』
http://www.amazon.co.jp/exec/obidos/ASIN/4274066401/

前田さんのサポートページ
http://awdwr.shugo.net/

出版社のページ
http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=4-274-06640-1

Amazonの先行予約は、Amazonの担当者の裁量で選ばれるもの以外は、出版社がペイを支払うことで実現するらしい。本書がどちらのケースなのか、残念ながら担当者レベルでは真相を知る由もないけれど、ずいぶんいろいろな人をお待たせしてしまった本だと思うので、少しでも早く予約可能になってくれてとてもうれしい。

ところで、巻末にある監訳者の前田さんの略歴には唐突に Scheme という文字が出てくる。あくまでも僕の主観では、これは「とても光栄な皮肉」だ。それはたぶん、この本の制作方法に関係している(あとで全体のフローをきちんとまとめること)。少しでも発行を早めるには、ほかに手段がなかったと信じているのですが、関係したみなさんには多大なるご迷惑をおかけしました。

2006/02/21

何かを観察したいっていうのは、人間の根源的な欲求のひとつだ。観察することにより周囲の危険や将来の出来事を想定したいとか、観察には科学の萌芽があるとか、そういう小理屈はぶっちゃけどうでもいい。ただ単純に、それをもっと見つづけたいという素朴な欲求があると思う。なんていうか、好奇心という概念だけではすませられない、観察という欲望。

たとえば交通事故の現場に遭遇したら、どうしたって見てしまう。不謹慎でも興味本位でもなく、ただ「何がどうなっているのか」を観察せずにはいられない。それだけ。事故や事件の現場はあえて避けて通るという人でも、映画のロケなんかやってたら、(別に興味なくても)とりあえず何を撮っているのか気になって、ちら見程度はすると思う。あと、おとこのこだったら、スーパーカーとか、通りの向こうを走り去っただけで凝視しない? それはもう、興味があるからとか、好きだからとか、カッコいいからとかじゃなく、とにかく見たい。もっとよく見たい。

女の子のスカートが短いのとかも、そのような事例に含まれると思う。いちいちセクシャルな感情を強く抱く男性もいるとは思うけど、そんなのは基地外であって、もっと単純に、ただ状態を観察したいというのが、個人的には本音だったりする。ほとんど交通事故とかと同じ。いちいち性的感情を抱くほど頭のなかはヒマじゃない。異性の下着=性的感情という短絡なイメージは放棄してもらいたい。小学生じゃないんだから。

というはなしを会社でしていたら、おまえは逮捕されてしまえと嘲笑された。だれに嘲笑されたとは、あえていわない。

2006/02/19

『亡命ロシア料理』のローストビーフがうまそうでたまらない。やつらは壺の中にタマネギのみじん切りを敷き詰め、そこに牛肉のブロックを置き、白ワインだけ加えてオーブンにかけるらしい。塩も加えない。タマネギと牛肉のエキスだけをスープにして、あとは壺に任せる。これで極上のローストビーフができるんだって。

このレシピは、化学的にも正しいと思う。NaClのような、分子が小さいわりに味覚を左右する調味料を最初から使ってしまうと、肉汁がしみ込む余地がタマネギの細胞になくなるし、タマネギの甘みがしみ込む余地も牛肉の細胞からなくなってしまう。アミノ酸の分子は塩に比べると巨大だから。

ただ、どうにも我が家には壺が見あたらないので、この知見を応用してスープを作ってみることにした。無水鍋(商標はピタクラフト?)でオリーブ油を加熱し、大量のタマネギのみじん切りを胡椒で軽く炒め、その上に豚コマを設置し、白ワインを半カップほど注いで弱火にかける。5分くらいで十分に水分が出てくる。さらに白菜を投入して、白菜がイメージどおりにしなしなしてきたら、ひたひた程度に水を加える。最後に塩とかサドンデスソースで味付けするだけ。これはうまい。

ここまでは数週間前の話。

今日は、このスープで得た知見を、さらにカレーに応用してみた。カレーを作るとなると下ごしらえに2~3時間くらいかかっちゃうわけで、2~3時間というのは、仮にそれくらいの物理的な時間ができても、実際に不慣れな行動を起こすのはおっくうだったりする。そこで亡命ロシア流タマネギの下ごしらえですよ。

まずはスターターオイルを作る。いずれもホールのクローブ、クミン、カルダモン、黒白胡椒を砕いて、火にかけた油に投入する。焦がさないように注意。油に香りが移ったと信じたら、タマネギのみじん切りと生姜を炒め始める。今回は亡命ロシア流なので、タマネギから出る水気をとばさずに、白ワインだけ加えてタマネギ自身の水分で煮込んでいく。そのため保温鍋(商標はシャトルシェフ)を使う。全体に火が通ったら、頃合いを見てマンゴチャツネやヨーグルトも投入する。チャツネとか、いままでは最終工程に近いとこで入れてたんだけど、分子の大きさを考慮すればこのタイミングだよな。あとは保温鍋にまかせて1時間くらい本でも読んでれば、下ごしらえは終了。

タマネギの下ごしらえができたら、別に茹でておいた豚バラ肉をスープごと加えて、具を煮込む。今日はジャガイモとにんじんとトマト。具材の煮込みも保温鍋に任せる(壺はもってないし)。やっぱり1時間くらいしたら、コリアンダー、ターメリック、ガラムマサラを加え(今日の比率は2:1:3)、最後に塩で味を整えて完成。

curry

従来よりも味のまとまりがいいような気がする。そういえば、にんにく忘れてた。

2006/02/14

先日、『ホテル・ルワンダ』を見に行った。日本公開のためのWeb署名をしたような記憶もあったので。

この映画はとてもいい作品なので、見に行ける人は見に行ってください。
ぶっちゃけ、いまこの映画を見に行っている人は、80%はルワンダやコンゴで何があったか(ニュースとして)知っている人だと思うし、そのうちのさらに80%は、この映画で語られている時間のに何があったかも(ニュースとして)知っていると思う(フツでもツチでもない、コンゴのカビラ政権のことね)。でも、そういう人たちが見に行っているだけでは、いつまでたっても政治臭い作品だとみなされてしまう。まあ、旧社会党系と共産党系の皆さんにもぜひ見てもらって、生ぬるい頭をかちわってきてもらいたい部分もあるけど、この映画は、ただの政治ツールにしてはいけない。だから、やっぱり自衛隊反対とかいってる人は見に行かなくていいです。かといって右翼も見に行かなくていいです。普通の人に見に行ってほしい。すべからく社会人は、ポールのかっこよさを見て、ああ、ぼくは明日も同じような仕事の繰り返しかもだけど、プロとして、会社とか目の前の客とか中途半端な職業倫理なんかじゃなく、ほんとうの品格をむねに自分の仕事に向き合わなくちゃだめだなあと痛感してほしい。実践するのはむずかしくても。

自分の今の仕事が、自分が何かをつっぱってまで品格を保ちたいと思えるものかどうかは大部分の人にとっては問題で、そのジレンマが、高々「お金をもらっている以上……」とか、「人に出して恥ずかしくない……」とか、そういう職業倫理に落ち着いちゃうんだよなあと、自省を含めて感じる。

レイトショー中心だったりするから、かえって大人は見に行きやすいと思う。

2006/02/11

そういえばきのう T さんに、「ブログにプログラムとか書いてるのは正直どうかと思う」と言い放たれたのを思い出した。かわいらしいくせに言うことはこにくたらしい。
小学校の教員的には順序を付けるのは NG なんだろうけど、数学、とくに集合論では、ある関係によって順序を定義し、集合の要素を整列させたい。ある順序集合が整列できるかどうかは、少なくとも「なんとか伝票のどこに印鑑を押すか」よりは重要な問題なのである。だから邪魔しないでください。

あるリストを集合だと思って、その要素 a と b の関係「a > b」を、「a が b よりもリストの左側にあること」だと考えることにする。そのリストの部分集合(必ずしも降順に並んでいない)を、重複する要素を除外して降順に並べるには、どうやるのが効率的か。つまり、
(a b c d e f g h i j)
というリストがあって、その部分集合、たとえば
(f c a c)
を、もとの親玉のリストと同じ順番
(a c f)
にしたいというはなし。

たぶん、これは、ソートの問題の一般化なんだと思う。順序を定義しているリストをランダムアクセス可能なデータ構造に対応させて、関係「>」を自然数における「>」と同一視してクイックソートかなんかしちゃうのがひとつの解法なのかもしれない。つーか、Cとかで配列を使うなら、自然にそういう方法を選択していることになる。

リストのまま整列させるにはどうするんだろうなあと一時間考えて、ようやくたどり着いた貧相な解法は、ビンソートっぽい方法。
(define (be-same-order ls1 ls2)
(if (or (null? ls1) (null? ls2))
'()
(let C ((ls ls1)
(passed '()))
(cond ((null? ls)
(be-same-order ls1 (cdr ls2)))
((equal? (car ls) (car ls2))
(cons (car ls)
(be-same-order (append passed (cdr ls)) (cdr ls2))))
(else
(C (cdr ls) (cons (car ls) passed)))))))

なんでこんなことを考えているかというと、SICP の ex. 2.84 のせい。2種類の型のどっちがどっちを包含してるか判定する方法を示せっていうんだけど(たとえば有理数と実数はどっちがどっちに含まれるか?)、意味を分離させて機械的に判定するには、あらかじめ数値型のタワー構造を表すリスト (complex real rational integer) を用意しておいて、上の be-same-order みたいなので (type-of x) と (type-of y) を整列させてから car をとればいいじゃん。いいじゃん、とか安直に思って、肝心の be-same-order みたいなのがすぐに用意できない、このどうしようもなさ。

2006/02/05

僕みたいな環境で Scheme を使うのは、子どもがクローゼットにしまってあるショットガンを見つけて弄んでいるのと同じなのかもしれない。
昼過ぎに柏から友人Kがくる。仕事を中断して奥様が作ったドライカレーを3人で食べて、しばらくたあいない(たわいない?)話をしてた。たぶんこれはとても贅沢なことなんだと思う。

2006/02/01

今日の LaTeX おばかちゃん。
  • どうグルーピングしても\kernにマイナスの値を指定できない場合がある。マイナスの値を指定した\kernを定義に使っているコマンドに対して、さらに \kern-1zw とかできないっぽいという挙動が、なんとなく見受けられる
  • \item[]の中に"["と"]"を入れるには、[]の中全部を{}でグルーピングする。エスケープしても無駄

ようするに、定義域がはっきりしなさすぎってことか。
むかし、ねえさんと文通してた KM が、2/14 にいよいよ結婚するらしいよ。という電話をさっきうけた。
正規表現に慣れすぎていて、構文解析とかやったことない。しかし避けても通れそうにないので、「10分で書ける、お手軽パーザー」というサイトを参考に四則演算のパーズに挑戦してみることにした。目標は1時間(つまり昼休み)。

10分で書ける、お手軽パーザー
http://fxp.hp.infoseek.co.jp/arti/parser.html

ところで、このサイトの構文定義っておかしくない? 左から解析することを前提にすると、オペレータの右側は必ず Expr のはず。
Expr = Term { (+|-) Term }
Term = Fact { (*|/) Fact }
Fact = ( Expr ) | number

Expr = Term { (+|-) Expr }
Term = Fact { (*|/) Expr }
Fact = ( Expr ) | number


とにかくやってみる。計算の優先順位を示すカッコのパーズは省略。
;; 10minutes-parser.scm
;; 2006/2/1
;; k16.shikano
;; inspired from http://fxp.hp.infoseek.co.jp/arti/parser.html

; Expr = Term { (+|-) Expr }
; Term = Fact { (*|/) Expr }
; Fact = Expr | number

(define left car)
(define op cadr)
(define right caddr)

(define-syntax or-match
(syntax-rules ()
((_ e0 e1 e2 ...)
(call-with-values
(lambda ()
(let R ((ls e0))
(cond ((null? ls)
(values '() '() '()))
((or (char=? (car ls) e1)
(char=? (car ls) e2)
...)
(values '() (car ls) (cdr ls)))
(else
(call-with-values
(lambda () (R (cdr ls)))
(lambda (l o r) (values (cons (car ls) l) o r)))))))
list))))

(define (expr ls)
(let ((parsed (or-match ls #\+ #\-)))
(let ((l (left parsed))
(r (right parsed))
(o (op parsed)))
(cond ((null? o)
(term l))
((char=? o #\+)
(+ (term l) (expr r)))
((char=? o #\-)
(- (term l) (expr r)))
(else
(error "unrecognize expr"))))))

(define (term ls)
(let ((parsed (or-match ls #\* #\/)))
(let ((l (left parsed))
(r (right parsed))
(o (op parsed)))
(cond ((null? o)
(fact l))
((char=? o #\*)
(* (fact l) (expr r)))
((char=? o #\/)
(/ (fact l) (expr r)))
(else
(error "unrecognize term"))))))

(define (fact ls)
(define (list->integer ls)
(let F ((ls ls) (added 0))
(let ((car-int (digit->integer (car ls))))
(if (null? (cdr ls))
(+ car-int added)
(F (cdr ls) (* (+ car-int added) 10))))))
(if (not (char-numeric? (car ls)))
(error "unrecognize fact")
(list->integer ls)))

実行結果

gosh> (expr (string->list "1+3*2"))
7


なんとか昼休みで終わらせたので、不都合があるかもしれない。
もちろん、今日の昼休みだけで全部作れたわけはなく、昨晩から or-match の部分は考えていた。この方法を Scheme で書くには、こんなふうに多値を使わざるをえないように思える(この使い方が洗練されているかどうかはおいといて)。それが面倒。