2w3ml.rb って名づけて見たけど、イマイチ。
展望:
scmail で出来るという噂。うひー。
簡単に手続きを渡したいなぁ。どういうルール記述にすると綺麗なんだろうか。うーんー。
RULES = [ Rule.new('X-ML-Name', /(.+)/)), Rule.new('From', /dareka@/){|mail| redirect_to('daresore', mail.to_s) }, ... ]
デフォルト以外のaction の記述がブロックかなぁ。
で、何種類か、簡単なアクション記述のベースがあればいいか。スルーするか、ってのはどう記述すればいいか微妙だなぁ。hoge: huga な記述を採用して置いてけぼりにするとか・・・。
なんか付けてけば付けてくほどでかくて醜悪になっていく。
m2n.rb に決定。
とりあえず動いた。
TMail を通したら、Subject が化け化け。そうか、一度 TMail::Mail#to_s してるからか。どうしたもんかな。
公開できるやつもできないやつも一緒くたにするので、公開はできないか。w3ml のリスト機能を潰せばいいだけかな。
TMail::Mail#to_s("\n", 'n') でも変わんない。んー。どうしたもんかなぁ。
encoded を使えばいいのか。ドキュメントはよく読まないと・・・。
できたできた。
このタイトルはなかなかうまくいった。
来てる SPAM のあて先上位6
383 paulc@at 331 everyone@at 56 kvdohahn@at 44 felyx@at 42 kvhdoahn@at 24 willie@at
irc で聞いたんですが、アイドルマスターWEB pre-debut edition。いや、ゲームの内容とか(声優とか)はどうでもいいんですが、凄い綺麗に動くねー。ここまで来たか。技術マンセー。
しかし、単語狙いすぎ。
・・・んー、違うか。べたーっとした塗りだから、そんなに難しいことでもないのかしらん。
TMail のリファレンスに body= が無いので悩んでしまった。
Emacs Lisp を Emacs 拡張用の言語って書いてあるけど、Emacs を構築するための言語じゃないのかなぁ。
def qsort lst return lst unless m = lst.pop qsort(lst.select{|i| i>m}) + [m] + qsort(lst.select{|i| i<m}) end qsort [] = [] qsort (x:xs) = qsort [y| y <- xs, y > x] ++ [x] ++ qsort [y| y <- xs, y < x]
def qsort(lst)(m = lst.pop) ? (qsort(lst.select{|i| i>m}) + [m] + qsort(lst.select{|i| i<m})) : [] end
なんか違う言語だ。
qsort = lambda{|x, xs| x ? (qsort[xs.select{|i| i>m}]+[m]+qsort[xs.select{|i| i<m}]) : []}
で行けるかと思ったが行けなかった。これがいけたほうがかっこいいと思うんだけどなぁ。
def qsort(x=nil,*xs) x ? (qsort(*xs.select{|i| i<=x}) + [x] + qsort(*xs.select{|i| i>x})) : [] end qsort(*lst)
def qsort(lst) x,*xs = lst; x ? qsort(xs.select{|i| i>=x})+[x]+qsort(xs.select{|i| i<x}) : [] end # irc で nokadaさんに伺いました qsort = Proc.new{|x, *xs| x ? (qsort[*xs.select{|i| i>x}]+[x]+qsort[*xs.select{|i| i<x}]) : []}
まつもとさんが既に qsort 書いてた・・・。
partition なんてあったのか。
def qsort(lst) x,*xs = lst; x ? xs.partition{|i| i<x}.map{|e| qsort e}.insert(1,[x]).flatten : [] end
うーん、長くなってる余寒。
もう短くならないかなー。
日本語で長いんなら圧縮すりゃいーじゃん!
require 'zlib' require 'uri' str = '研究日記でした。多分。' buf = Zlib::Deflate.deflate(str) p buf.size p URI.escape(str).size p URI.escape(buf).size #=> 31 60 77
増えてるし。
自分だけの世界だと、狭くて一歩も歩けない。
広い世界を見ると、怖くて一歩も歩けない。
どうも私は人の求める会話を提供することが出来ないらしい。
研鑚あるのみか。
黄泉がえりを見る。ホラーだと思ってたんだけど。久しぶりにたくさんテレビを見た気がする。
あんりみてっどなんとか終わり。やっぱりあっさり。
誰の日記にも登場しないので。
高橋さんのメールから引用: 場所: 東京・井の頭公園(予定) 日時: 4月3日(土) 15時か16時くらいから (その後でどこかのお店に行く予定) ※場所も日時も変更になる可能性があります。 花見連絡用MLを作りましたので、参加したい方や興味のある方は こちらのMLに登録してください(かずひこさんとこのQuickMLを お借りしています(_o_))。 MLに登録するには、 To: ruby-hanami-tokyo@ml.fdiary.net Cc: maki@rubycolor.org 宛てにメールしてください。自動的に登録されます。
多分、当日飛び入りでも参加可能じゃないでしょうか。しかし、さすが高橋さん効果。
The Student Day に行って来ました。VS.Net アカデミック無料でプレゼントってのに釣られていったんですが。
さすがにプレゼンは うまいですね。内容については何もいいません。悪口にしかならない。
持ってる金が違う。まさに物量が違う。火力が段違い。
夢はこのイベントを将来東京ドームで開きたい、みたいなことを言ってたけど、それが射程距離に入っているのがやはり強い。
とりあえず VS.Net Ver.2003 は貰ってきたけど、どうしようかな。これを機に C# でも勉強するか。
Ask experts ってコーナーが最後にちょろっとあったんだけど、「(後輩に凄いのが出てきて)危機感はないのか、モチベーションの維持は」って質問に、「好きなことなら」云々と答えていたのは、まぁそうなんだろうなぁとか思ったり思わなかったり。
登さんは会社作るんですってね。知らなかった。三菱マテリアルと共同でなんかするとは聞いていたけど。
VS.Net が欲しくて行った私とは大違いです。
X-ML-Name とかが書いてあったら、勝手にメーリングリストとして解釈して、勝手にフォルダ(なりなんなり)作って振り分けてくれる何かは無いもんだろうか・・・。で、勝手にやるパターンは自分で定義可能。自分で作るしかないのかなぁ。
てきとうに選んで適当に w3ml に投げるフィルタなら出来るかも。作ってみるかなぁ。
せっかく用意したのに、右や左に票を入れる人は居ない。
ルールの記述は正規表現書かせればいいかなぁ。
RULE = { 'X-ML-Name' => /(.+)/, # 'List-Id' => /(.+?)\.?/, # 'To' => [/daresore/, 'dokka'], } ... RULE.each{|h, r| if mo = r.match(m[h].to_s) thorw_to_w3ml(m, mo[1]) end }
こんな感じ?
ルールの記述がもっと柔軟じゃないとダメか。
配列がきしょい。
順番も欲しいから配列か。
RULE = [ ['X-ML-Name', /(.+)/ ,], ['List-Id' , /(.+?)\.?/ ,], ['To' , /dareka/ , 'dokka'], ] ... RULE.each{|h, r, to| if r =~ (m[h].to_s to = $1 if to.nil? thorw_to_w3ml(m, to) break end }
複数のルール、難しいルールなんて作らない。
競合したらどうするか。ML の名前が同じだったらってことだけど。
・・・無視無視ぃ。
w3ml には任意のディレクトリに作るってオプションがないのか(configure時に決まる)。うーん。
恥ずかしながら、やっと最近 vi の使い方を勉強しはじめました。J を知らないで、いままで全部書き直していたり。
Site Administration Course。おお、凄いわかりやすい。
at at atdot dot net でも作るか・・・。何に使うかが問題。
ダメダメなコードレビューが流行ってるのか。俺もなんか探してみるかな。まず自分のコードを見たほうが早いか・・・。
bot: googlec: じゃあ、麻雀で勝負よ(2), じゃあ、プログラミングで勝負よ(0)
さすがに無いか。
MLはー、とか書いてみて思ったけど、リストとsection の使い分け、もう少し必要なんじゃないかと考えてみる。
そうかー、Wiki名(っぽいもの)を検索にするのかー。その逆がはてなか。
私は WikiName って嫌いだから全部ブラケットで囲んでしまえって思うんだけど。
というわけで、BitChannel::ToHTML はどの程度差し替えやすいのかなぁ、と見てみる。あぁ、gsub ってこうやって使うのかー、と今更ながらに関心する。compile さえあればいいのかしらん。あと、なんかもうちょっとか。
にがんばって変更してみよう。
何年も前から考えていたことなんだけど、コンテンツと編集画面ってくっついてる必要ないよな。
/view/xxx.html # translated from xxx.txt yyy.html # translated from yyy.txt ... /raw/ xxx.txt yyy.txt /edit/edit.cgi ## protected page
こんな単純な構成でもいいから、早く実装したかったんだけど、やる気がなかなか。BitChannel を改造して、こういうことをしてみたいなぁ。
../prog/ なんてのは、そういう構成「になることを前提に」作ってあるんだけど、面倒で全然すすめていない。
こんな単純なことなのに、聞いたことがないのは私の知識不足だろうけれど、単純すぎて世に出ないってこともあるんだろうか。やっぱり。
kahua で作れーって声が聞こえてきそうだが。
ローカルでこういう構成にしてる人の話は結構見るんだけど。マクロで変換するとか。
積もり積もったいろいろが降って来る・・・。
眠いよー。うーん。
LL Mag. を買ってくる。ついでにC Mag.も。Cマガは惰性だ。全然読んでねーし。あまり興味を弾かないんだよな。
LL Mag. は nobsun の記事を読むためです :)
この内容で ¥2k か・・・。
知らなかった。java って return EXPR;;
って書けないのか。
この文に制御が移ることはありません。
3,4時間ほど、100台ほどのPCのセットアップを一人で黙々とやる。死ねる。イジメだ、これ。
うーん、pycon 羨ましいなあ。
お約束:『Kahua で作れーっ』
天泣記 2004/03/27 より:
やはり、他の人の要求は自分自身で気に入ったもの以外ことごとく reject して、自分が一番頻繁に使うところに最適化した最小の記法を提案したほうがいいのかも。
そうすると、マクロマンセーって話になるんですかね。
qmailmrtg7 を使おうとしたら、multilog というのが必要らしい。daemontools にあるらしいが、よくわかんなかったんでとりあえず諦める。
qmail のログさっぱりわからん。
自宅からどうやってメール送ろうかなぁ、やっぱpop before smtp かなぁ、と考えてたんだけど、ISP(nifty) の smtpd に送ればいいんだな。利用規定的にどうなのかよくわからないのであれだけど・・・。
一応探したけど、みつからなかったんで、まぁいいんだろう。
Windows用メーラを探してみるも、なかなかコレというものがない。まだまだ当分は den8 かなぁ・・・。
akrさんに聞いた tail で一気読み。いいかも、これ。あとはメールの着信とかをこいつに流せば。
で、チャットのログの場所とメールの場所(マシン・ネットワーク)が違うんだけど、どうするのが賢いか。
iptables の LOG をぼけーーーっと眺めてみる(現実逃避)。なかなか楽しい。
... atdot kernel: input drop: IN=eth1 OUT= MAC=... SRC=... DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=1 ID=... PROTO=2
なんてのが、多分gwから大量に来てるんだけど、PROTO=2 って、なんだろう? 何をブロードキャストしてるんだろう。ルーティング情報とか、そういう話かな。
って、IGMP ってもろに書いてあるじゃん。さて、これは落としていいものなんだろうか。
Cross じゃなかったんだ・・・。
日記のメールインターフェースですか。どうしようかなぁ。
procmail のルールは難しくて書けそうにないので、自分でなんか作るかなぁ。
def inspect end class C end p C.new.inspect
嫌がらせ。
花見をしてくる。寒すぎ。アルコールじゃおっつかない。
つーか桜あんまり咲いてないし!!
ひろーーい公園に、数組。でも、俺ら以外に居たのが意外だった。馬鹿はどこにでも居るもんだなぁ。
SPAM が100通くらい、さくっと来る。
grep "^To:" * | uniq ざっくり略。
なんか、paulc さんにたくさん来てる? あと Bryny さんか。
irc で聞いたんですが、☆あさりちゃんのへや☆。まだやってたんだー。知らなかった。しかも、いろんなブランチがあるのねぇ。
やっぱり apop くらい入れたいなぁ、と思ったんで、ちょびっと探す。uw-imapd, solid-pop3d, courier-pop など、か。さて、どれを使おうかな。
ilohamail というweb mailクライアントもあるのか。
ここではだれもが愛用しているエディタ、viを起動してみた。
そうですか。
ToDo:
back up はどうしようかなぁ。
とりあえず /etc 以下とか固めておこうかなぁ。
あまりにアレなのでもうちょっと整理。
adds = Hash.new(0) open('t'){|f| f.each{|line| if /(\w+@)/ =~ line adds[$1]+=1 end } } p adds #=> {"kvdohahn@"=>3, "root@"=>1, "kvhdoahn@"=>1, "leo@"=>1, "paulc35@"=>2, "bryny@"=>55, "gwsrhokwrnmaaum@"=>1, "felyx@"=>8, "paulc@"=>74, "everyone@"=>50}
やっぱり paulcさん宛てが多い。昔使ってたんだろうか。このドメインで。
とりあえず、paulc, bryny, everyone 宛ては無視するようにしておくか。
さて、/var/qmail/alias/.qmail-default (あて先不明のメールのあて先)は必要か。
メリット、デメリットがあるだろうけど、とりあえず必要ってことで。この運用では可能だ、というのもあるが。
quickml.atdot.net なんてのを作ってみる。
勝手に使ってください、っていうには、ちょっとマシンパワーが足りない(Pen3 500Mhz)ので、たとえばあるアドレスからでしか作らせないようにするには・・・。
initialize を弄ればいいんかな。init_ml_config で @ml_config_file が存在しない、かつ @address != 誰か、ってやっとけばいいのかな。てけとーに rc にそういうの足せるようにしといて。
あかん、httpd.conf の書き方忘れてる・・・。
だせー。
なぜ public_html 以下が見れないんだ、と思っていたら、~/ の permission がきつかっただけだった。うはー。
mrtg を付けてみる。
大量だ。
control/doublebouncetoを使って、ダブルバウンスを専用のユーザに送り、数日間だけ保存して捨てるのが良いと思います。~alias/.qmail-defaultは無しで。
"no mailbox here by the name" の bounceメールを騙った Return-Path へSPAMなりウイルスメールなりを送りつけてしまうのが嫌だな、と思ったのですが、どうでしょうか。いろいろgoogleしてみたんですが、「defaultあるべき」と「ないべき」両方あるようで、正直どっちがいいのかよくわかりません。
あと、日記中、「この運用では」と書いたのは、使うのが私(+α)なので、アドレス間違いしたやつを覗いてしまうようなプライバシの問題があまり生じない、というのがあります。
defaultつけるんなら、読まずに捨てるんでしょうね。それも良いかも。「ほんとに間違えた」人には不便ですが。
15時間くらい寝てしまった。
route の設定がダメだったっぽい。debian でこの設定を起動時に復帰させるにはどこに書くんだろう。network/interfaces なのかな。
OGIS-RI OBJECT SQUARE。今月はインタビューはなし。
「オブジェクトの広場編集員が贈るオススメ書籍:◆◇ オブジェクト指向書籍編 ◇◆」に RHG があるのは何故だろう。
オススメであることに異論はないんだけど。
atdot dot net というドメインの運用を開始してみました。暇だったら、 ko1 at atdot dot net というメールアドレスに、よかったらメールを投げてもらえませんか。メールサーバの運用ははじめての経験。
ファイル名がずらずら並んでいて何かと思ったら rdoc の作成だった。びびった。
そういえば青木さんに使えと脅されたので zsh にしてみたんですが、まだ bash との違いが感じられません。
まぁ、使ってないだけだと思うんですが。
例の SimCity Classic は Java を使ってるみたいですね。なんかタスクバーに出てきたので。
woody を入れたんだけど、autoconf だけ unstable が欲しい。はて、どうやるんだろう。apt-get autoconf/unstable だとみつかんねー、と仰る。
/etc/apt/sources.list に sid な奴を加えて見ると、なんかエラーを吐きやがる。(E: The package lists or status file could not be parsed or opened.
)
はてな?
って、メモリ不足なだけか・・・B
うーん、Wiki ほしいなぁ。
卒業式だったらしいんだが、まぁいつもどおりまったりと。何も変わらない日常。
んー。
リモートから pop で取ろうとすると 10秒くらい待たされる。はて、これは一体。ローカルでは全然待たないんだけど。
ident の話だったらしい。
とりあえず、だいたい設定は終わり。ssl とかは今すぐ必要でもないだろう。
qmail たてたらサクサクといろんなものが飛んできて面白い。
現状では rcpthosts を制限してるから、外から smtp できないけど、家からも建てたいよなぁ。pop before smtp は面倒なので、smtp auth でもたてるか。それとも、おうちは許可するようにしようかなぁ。
ssh を堅牢に利用するには何が必要だろうか。ssh の利用履歴を全部メールするとか必要なんだろうか。
「Squeakプログラミング入門 - オブジェクトランドへの招待」のWebサイトにようこそ!(smlとか)。ほしいなぁ。読みたいなぁ。
ssh 、家からは繋がらなかった。ssh のクライアントのバージョンが古いらしい。
って、あれ、おかしい。バージョン一緒やし。
うーん・・・。
iptables のテストのためにとりあえず -F で全部けしてしまえー、と思ったら policy は全部 DROP。やっちまった。学校行かないと戻せない。
autoload -U compinit; compinit したときの補完機能は、他の追随を許さないものがあります
あとコマンドラインスタック、alias -g、複数行ヒストリあたりが大きな差でしょうね(bashはほとんど触ったことないんですが……)。
=cmd と =(cmd)、*(/) なんかも捨てがたい。
っつーか、どうしてakrさんの SDのzshの原稿を読んでないんだか(ぶんぶん
読みました。んですが、ruby あんまり作らないですし。
いつの間にかとーひょーが下の方に。というわけで、次のアンケートはmain()は上に書くか下に書くかを。
上、下、中、なにそれ、の4択?
BIOSアップデートのため、起動ディスクを作ろうとして頑張る。
Win2000 には /S が無いのねぇ。
ディスクを認識しないのはなぜだ! とずっと悩んでいたら、ただ単にジャンパの位置が間違っていただけだった・・・。
で、改めて FreeBSD を入れようとしたら Kernel パニック!
これはもう、俺に FreeBSD でサーバ立てるな、という啓示か。
おとなしく Debian 入れるか・・・。うーん、なんか負けた気分。
panic する原因がわかった。BIOSアップデートして、メモリの設定が飛んだからだ。・・・多分。
というわけで、FreeBSD 再挑戦。
勝手に切り分けてくれるパーティションじゃぁすくねーといいやがる。
ざくっと swap に 128M 、残りを / にしてやり直す。
Write failure on transfer! (wrote -1 bytes of 24060 bytes) /: write failed, file system is full
同じエラー。何かを根本的に間違えてるんだろうか。
うーん。わけがわからん。
やっぱ諦めようかな・・・。ftp でインストールってところがいけないんだろうか。
ちょっと電話してたら2000円とかになってしまった。ガーソ。
Article 36 at 04/02/25 12:19:57 From: editors@ObjectClub.esm.co.jp Subject: 【オブジェクト倶楽部: 2004-07 号】。Ruby が一言も出てこない CodeKata。まぁ、Ruby とは関係ないか。
結局 debian にした。
iptables が動かんー・・・と悩んでいたら、2.2.20-compact だった。動くわけがない。
さて、どうやってアップデートするのかしらん。
てきとーにやったら panic った。ごにょごにょやってたら動いた。initrd について加える必要があったらしい。
"--help" という名前のディレクトリを消すにはどうしたらよいか。> rm -- --help
。感動した。
あなたの 非モテ度は
71%です
判定:非モテの達人
LLVM、最近チェックしてなかったなぁ。
たとえば lambda{return xxx} を block と同じセマンティックスにして困る人/困らない人はどれくらいいるんだろうか。
正規表現で埋め込むくらいなら、普通に recieve 使ったほうがよくないでしょうか。
(receive (a b c) (regexp-match-values #/..(a)(b)(c)../) ...)
DOSディスクの作り方 http://hamanasu.sakura.ne.jp/~yami/notes/cop4.html
FTPさーばからうまく拾えてないのでしょうかねぇ. 以前そのエラーどっかで見たような気がします.
全部/にするとi-nodeが足りなくなるとか?
まさにそれで作りました>DOSディスク
2004-11号の[1]ではちゃんと言及されてますよ>CodeKata
rm ./--help
つーかrmdir
インストール中の/はメモリ上のディスク(mdかな?)になっていると思いますが、 なんかそこに展開されちゃうことがあるみたいです。というか、実際ありました。 オプションの画面で展開先のディレクトリを適当に指定すればOKでした。 F4だか何だかを押してshellの画面を出してdfしてみるといいと思います。
あー、なるほど> ./-- 。df も気づきませんでした。
ぼーっと髭を剃ったらざっくり唇を切ってしまった。肉が髭剃りについてるし・・・。
なれないことはするもんじゃない。
f2e とかやっていると、怪我しても全然平気な気がしてくる。もちろん、気だけ。
まったりと研究室。
ラーメン強し。
その他がないのは、やっぱりその他はあまり無いのか。
さて、17日賞味期限のパンは食えるのか。
direct threaded code は、随分前にねたにした気がしました。
いや、しかし先週のことなんてよく覚えていますね。私はさかいさんが自分のことを棚にあげてダメ系のネタに対し非常に冷たかったことしか覚えていません。
こわっ
お疲れ様でございました。たいしたおもてなしもできず失礼しました。
あれだけの力量の差をみせつけられると、こういっそ清々しいというか。
いえいえ、お世話になりました
研究室で飲み。久々に激しく飲み。とても気持ち悪い。
i,j,k はこれ以上略せません(違)。
二日酔いで何もやる気がおきない。
root のパスワードを忘れたので(ダメスギ)、せっかくだから FreeBSD をインストールすることにした。
で、インストールしようとして格闘して数時間。出来なかった。
どうやら、HDDが逝ってるようで。どうしようかな、これ。
明日買ってくるか。新しいの。
Wiki の stylesheet も編集可能にしちゃったらどうなるだろう。セキュリティホールになりそうなのってあったっけ?
月刊Emacs。
bot: googlec: 月刊Emacs(1110), 月刊eclipse(1240), 月刊vi(2610), 月刊Visual Studio(1140), 月刊tex(879)
bot: googlec: 週刊Emacs(1260), 週刊eclipse(1590), 週刊vi(3760), 週刊Visual Studio(812), 週刊tex(733)
さすがに週刊は・・・。
bot: googlec: 季刊Emacs(119), 季刊eclipse(105), 季刊vi(708), 季刊Visual Studio(93), 季刊tex(146)
vi 強いなぁ。
サーバ入れ替えたテストです
http://www.ipa.go.jp/security/awareness/vendor/programming/a01_02_main.html
もちろんそれなりにサニタイジングすればだいじょうぶなはずです。参考: http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%C0%A5%A4%A5%A2%A5%EA%A1%BCXSS%C2%D0%BA%F6?kid=1003
Java Script もなんでもできるんですね。使ったこと無いからしりませんでした。
なんとかの注文終わり。最後までわけがわからなかった。
irc で聞いたんですが、東大助教授を懲戒免職、院生を靴でたたく。
うげぇ。
栗本薫「壁」読了。
ホラーは苦手なんですが・・・。怖かった。まぁ、この人の作品ってやっぱ同じ人が書いてるなぁ、というか、グインサーガしかあんまり知らないんですが。オチのネタもねぇ、あれだし。
と、ついつい読みきってしまった。
魔界水滸伝読んでみようかなぁ。その前にクトゥルーよんどかないとあかんのかしらん。
研究室のウェブサーバ移転のため、もしかしたら明日とかつながらないかもしれません。
xmlmine、まさにキターって感じなのですが、Java版でしたか。面倒くさいなあ
複数のXML文書を食わせてれば、全てのファイルを見てマイニングやってくれるんでしょうか。しかし、説明書が日本語って素晴らしい。
TtoN を改良。はやくやろうやろうと思っていて、全然手をつけていなかった。
ただ単純に Wiki っぽいフォーマットを解析するだけなのに、なんか異様にてこずってる。頭悪すぎ。
- A - B -- BB - C
があったとき、
になる。
html では、
(ul (li A) (li B (ul (li BB))) (li C))
にしなきゃいけない。
さて、汎用的な構造として、これでいいのか? li の中の要素としなければならないというのは、使いやすいか?
TeX だと、
\begin{itemize} \item A \item B \begin{itemize} \item BB \end{itemize} \item C \end{itemize}
となる。閉じタグが無いので楽。
たとえば、またその構造をプレーンテキストとして表示したいとき、元に戻せるか? 戻せるだろうけど、単純なルールでそれができるか? li の出力時にulの数数えておけば、それでいいのかなあ。
他の構造だとどうだろうかなあ。
やっぱり、ul に ul 重ねちゃいけないってのは面倒くさい。
構造は (ul (li ...) ... (ul ...))
にしといて、出力するときに直前の li とまとめようかなぁ。でも、面倒くさい。
テーブルの文法をやっと決めた。
#| A | B | C | #+------------ #| A1| B1| C1| #| A2| B2| C2| #| A3| B3| C3|
もういいや、これで(投げやり)。
ガーーーーーーーン・・・・・・・・。
チケットまで買ったオーケストラ、すっかり忘れていた。
ガーーーーーーーン・・・・・・・・。
頭悪すぎる・・・・・・・・。
日曜日・・・、ダラダラ過ごしてただけだった・・・・。
ぅぁぁぁぁぁぁぁぁぁぁぁぁぁぁ・・・。
ぅぅぅぅぅぅぅぅぅ・・・。
ぁぅぅぅぅぅぅぅっぅ・・・。
札幌とか名古屋とか行けば、まだあるけど、財布が・・・。
ぅぅぅぅぅぅぅぅぅ・・・。
CD出るかなぁ・・・。
もう何もやる気が出ない・・・・・・。
当分研究なんて出来ません(もともとやってない)。
気持ち悪い。
require 'cgi' module XMLParts # tree ::= string # | [:symbol tree] # def tree2string tree case tree when String CGI.escapeHTML(tree) when Array sym = tree.shift attr = '' elems = tree.map{|e| if e.kind_of?(Hash) e.each{|k, v| attr += " #{k.downcase}='#{v}'" } '' else tree2string(e) end }.join "<#{sym}#{attr}\n>#{elems}</#{sym}>" else raise "unknown tree: #{sym}" end end def method_missing m, *args if sub_func? && (/^#{XMLParts.method_prefix}(.+)/ =~ m.to_s) [$1].concat(args) else raise NameError.new(m.to_s) end end def sub_func? true end def self.method_prefix '_' end def self.newtag sym, klass = XMLParts klass.module_eval <<-EOS def #{method_prefix}#{sym}(*args) [:#{sym}].concat(args) end EOS end end module HTMLParts include XMLParts def sub_func? false end # copy from cgi.rb PARTS_1 = %w{ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT TEXTAREA FORM A BLOCKQUOTE CAPTION } PARTS_2 = %w{ IMG BASE BR AREA LINK PARAM HR INPUT COL META } PARTS_3 = %w{ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY COLGROUP TR TH TD HEAD } (PARTS_1 + PARTS_2 + PARTS_3).each{|e| elem = e.downcase XMLParts.newtag elem } end include XMLParts puts tree2string( _hoge({"attr"=>"value", "attr2" => "value2"}, "hogehoge")) include HTMLParts puts tree2string( _html( _head( _title('hogehoge')), _body( _h1('huga-'), _p('hogehoge', _a('hogehoge', 'href' => 'dokka'), 'huga'))) )
結果。
<hoge attr2='value2' attr='value' >hogehoge</hoge> <html ><head ><title >hogehoge</title></head><body ><h1 >huga-</h1><p >hogehoge<a href='dokka' >hogehoge</a>huga</p></body></html>
XML というラベルはとても詐欺くさい。詳しいこと何も知らないしなぁ。
require 'cgi' module XMLParts class XMLItem def initialize tag, body @tag = tag.to_s.downcase @attr = body.find_all {|e| e.kind_of? Hash} @body = body.delete_if{|e| e.kind_of? Hash} end def to_s attr = '' @attr.each{|e| e.each{|k,v| attr += " #{k.downcase}='#{v}'" } } body = @body.map{|e| case e when String CGI.escapeHTML(e) when XMLItem e.to_s else raise "unknown tree: #{sym}" end }.join "<#{@tag}#{attr}\n>#{body}</#{@tag}>\n" end end def method_missing m, *args if sub_func? && (/^#{XMLParts.method_prefix}(.+)/ =~ m.to_s) XMLItem.new(m, args) else super end end def sub_func? true end def self.method_prefix '_' end def self.newtag sym, klass = XMLParts klass.module_eval <<-EOS def #{method_prefix}#{sym}(*args) XMLItem.new(:#{sym}, args) end EOS end end module HTMLParts include XMLParts def sub_func? false end # copy from cgi.rb PARTS_1 = %w{ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT TEXTAREA FORM A BLOCKQUOTE CAPTION } PARTS_2 = %w{ IMG BASE BR AREA LINK PARAM HR INPUT COL META } PARTS_3 = %w{ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY COLGROUP TR TH TD HEAD } (PARTS_1 + PARTS_2 + PARTS_3).each{|e| elem = e.downcase XMLParts.newtag elem } end include XMLParts puts _hoge({"attr"=>"value", "attr2" => "value2"}, "hogehoge").to_s include HTMLParts puts _html( _head( _title('hogehoge')), _body( _h1('huga-'), _p('hogehoge', _a('hogehoge', 'href' => 'dokka'), 'huga'))).to_s
<_hoge attr2='value2' attr='value' >hogehoge</_hoge> <html ><head ><title >hogehoge</title> </head> <body ><h1 >huga-</h1> <p >hogehoge<a href='dokka' >hogehoge</a> huga</p> </body> </html>
ちょびっとだけ ruby らしいか。ちょびっとだけ。
module XMLParts class XMLItem def initialize tag, body @tag = tag.to_s.downcase @attr = {} @body = [] body.each{|e| add! e } end def make_attr_str @attr.map{|k,v| " #{k.downcase}='#{v}'" }.join end def to_s "<#{@tag}#{make_attr_str}\n>#{@body.map{|e| e.to_s}}</#{@tag}>\n" end def inspect "<XMLItem: <#{@tag}#{make_attr_str}>>" end def add!(elem) if elem.kind_of? Hash @attr.update elem elsif elem.kind_of? String @body << CGI.escapeHTML(elem) else @body << elem end end def [](k) @attr[k] end def []=(k, v) @attr[k] = v end def each @body.each{|e| yield e } end def each_leaf @body.each{|e| if e.kind_of? XMLItem e.each_leaf(&Proc.new) else yield e end } end def each_node yield(self) @body.each{|e| if e.kind_of? XMLItem e.each_node(&Proc.new) else yield e end } end alias << add! end @@method_prefix = '_' def self.newtag sym, klass = XMLParts klass.module_eval <<-EOS def #{@@method_prefix}#{sym}(*args) XMLItem.new(:#{sym}, args) end EOS end def method_missing m, *args if sub_func? && (/^#{@@method_prefix}(.+)/ =~ m.to_s) XMLItem.new($1, args) else super end end def sub_func? true end end module HTMLParts include XMLParts def sub_func? false end # copy from cgi.rb PARTS_1 = %w{ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT TEXTAREA FORM A BLOCKQUOTE CAPTION } PARTS_2 = %w{ IMG BASE BR AREA LINK PARAM HR INPUT COL META } PARTS_3 = %w{ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY COLGROUP TR TH TD HEAD } (PARTS_1 + PARTS_2 + PARTS_3).each{|e| elem = e.downcase XMLParts.newtag elem } end
もういいや。
何を作っていたかと言うと(見ればわかるけど)。HTML とか、"<...>" とプログラム中に書くの面倒くさいし、ERb 書くのも面倒くさいし。ということで、もっと手軽に出来ないか、というのを考えてみた。もうどっかにありそう。ネタ元は何度も書いてるけど SXML、および Gauche の text.html-lite とか、その辺。
とくに、HTMLの一部を、"<xxx>#{...}</xxx>" って書いていたのが少しは楽になるんじゃないかなぁ。
require 'xmlparts' include XMLParts puts '-----------', _a( _b( _c1('c1str'), _c2('c2str'))) #=> ----------- <a ><b ><c1 >c1str</c1> <c2 >c2str</c2> </b> </a>
こう使う。_xxx で <xxx> ... </xxx> になる。
attribute は _xxx にHash で渡せばよい。Hash は何個渡しても良い。
_a({"attr1"=> "value1", "attr2"=> "value2"}, _b( _c1('c1str'), _c2('c2str')), {"attr3"=> "value3", "attr3"=> "value3"} ) #=> ----------- <a attr1='value1' attr2='value2' attr3='value3' ><b ><c1 >c1str</c1> <c2 >c2str</c2> </b> </a>
HTMLParts を include すると、_xxx の xxx は HTML 4.0(だと思う)の要素に限定される。多分。
本当に便利なのか、使ってみてから考えよう。
ちなみに、_xxx(...).to_s しないと文字列になんないので注意(puts は勝手に to_s してくれる)。
こういうの、絶対誰かが作ってると思うんだけど、不勉強なのでシリマセン。知ってたら教えてください。標準添付にあったらいやだなぁ。
パーサはいろいろあるけど、書くほうはあんまり無いような印象はある。
XML はやっぱ詐欺かなぁ。詐欺だよなぁ。仕様書見たことないしなぁ。なんか別の用語の略語にしておこうか。
文字列エンコード関係なんて触りたくも無いし。エスケープもいい加減。
PStore 使うときとかの dump で、ある attr だけ書き出したくない場合、どうしたらいいんだろう。
今回は、
attr = obj.attr obj.attr = nil db.transaction{ db[key] = obj } obj.attr = attr
で逃げた。
_dump 再定義とか面倒だし。
あー、marshal_dump ってそういうためにあるのかー。でも、今回は逆だな、〜〜以外を dump したい、だから。
XML: eXtensible Maid Layer
嫌すぎ。いいや、これで。
(use text.tree) (use sxml.tools) (write (tree->string (sxml:sxml->html `(ul ,@(map (lambda (e) `(li ,e)) '("a" "b" "c" "d"))))))
gaucheではこんな感じでしょうか。
(use text.html-lite) (write (tree->string (apply html:ul (map (lambda (e) (html:li e)) '("a" "b" "c" "d")))))
こっちかなぁ。ってか、まんまこっちですね。
apply 要らなかったらしい。
いやーん、アレした奴バグバグ。どうしよう。テストしてないのバレバレだ。
研究室へ帰室。また首が回らなくなってきた。幸せな生活よ、さらば。
上の、誰か使いそうならパックするけど、多分誰も使いそうにないのでいいや。自分で色々試してみよう。
先生、なんで class << self; class << self を2段重ねたりしてるのかさっぱりわかりません。
まだまだ ruby は不思議がイッパイ!(嬉しくない)
p class << self self end #=> #<Class:#<Object:0x2ac92e8>> オブジェクト self の特異クラス
p class << self class << self self end end #=> #<Class:#<Class:#<Object:0x2ac92e8>>> オブジェクトの特異クラス内の・・・なんだ、これ オブジェクトの特異クラスが内包する特異クラスか class C1 class C2 end end => C1::C2 と一緒なの? なんか違うような気がしないでもない。
なんとなく、 class << self; end を2度繰り返したら別のものが出来るような気がちょっとしたけど、もちろん気のせい。
XTemplate なり Amrita なりのテンプレートエンジンじゃだめなんですか?S式っぽくデータが渡せるのが目標?
どちらも使ったこと無いので(すみません)勘なのですが、テンプレート書くのが面倒くさいんです。多分。
全体のデザインを作るのは templateエンジンでなんかやるのがいいと思いますが(デザイナーさん云々)(これと排他になるものではないと思っています)、あるちょっとした部分、たとえば <ul> <li>...</li></ul> だけちょっと書きたい、ってときに template エンジンを使うのはやりすぎかな、とか、面倒だな、とか。ERb を使っただけの感想なのですが。
大げさってのはありますね。確かに。参考までに Amrita だとこんな感じです。
tmpl = Amrita::TemplateText.new <<END <ul><li id="name"></li></ul> END a = { :name => ['a', 'b'] } tmpl.expand(STDOUT, a) #=> <ul><li>a</li><li>b</li></ul>
(何度も書き直しててすみません) (笹田:ちょっと修正しました)
作った奴で書くとこんな感じでしょうか。
ary = %w(a b c d) puts _ul(*ary.map{|e| _li(e)}) #=> <ul ><li >a</li> <li >b</li> <li >c</li> <li >d</li> </ul>
なるほど。例えばtDairyなどのプラグインでHTML出力するときに一々テンプレートエンジン使うのは大げさだけど、ヒアドキュメントでXML/HTML書くのは冗長すぎてやってられないという感じですか?
そんな感じです。あと、構造として、文字列操作よりも把握しやすくなるんではないかと思います。
amritaではこういう書き方もできます。
% ruby -r amrita/template -e 'include Amrita; puts e(:a, :href=>"http://www.ruby-lang.org") { "ruby" } ' => <a href="http://www.ruby-lang.org">ruby</a>
1段だと marshal できないからです。2段だと marshal できる理由は [ruby-dev:22623] らしいですが、実のところ今一つ理解できません。
ありがとうございます。わか・・・りませんが、もうちょっと考えて見ます。
スティーヴンスン「宝島」読了。ジム少年のその後が気になる。
なんとなく、この日記も数式に対応してみたくなった。前から興味はあったんだが。
tex -> (dvi) -> dvips -> (ps or eps) -> convert -> (png/gif/...) というのがまぁ、標準らしい。
マークアップはこんな感じかなぁ。
#formula tex の数式 #end ... $$ inline な tex の数式 $$ ...
$$
ってどれくらい使うか微妙。
暇があったらがんばろう。
tton を htmlparts で全部書き直してみようかなぁ。
dangling method call では木構造は表現できない。。。よなぁ、多分。やっぱり木構造の表現が貧弱。
Pair リテラルに :( x, y )
なんてダメですか。そうですか。
:(:a . :b).car #=> :a :(:a . :b).cdr #=> :b :(:a , :b).car #=> :a :(:a , :b).cdr #=> :(:b . nil)
無理。
これやるなら、
%S{ (a b c) } #=> :(:a , :(:b , :(:c , nil))) #=> :(:a :b :c)
のほうがいいな。
・・・ダメですか。そうですか。私は欲しいけど。
素直に Scheme 使えよ! って?
:(x, y) #=> Pair(x,y) :{x, y} #=> Pair(x, Pair(y, nil))
考えれば考えるほどダメになっていく。
%?{ ... }
をプログラマブルにするって話、なかったっけ。あればこれができるのかな。
Why do bloggers kill kittens?(/.j)。
笑った。
配列の何が嫌か、っていちいち malloc が付くのが嫌なのですよねぇ。
面白かったけど、S式 = Functional じゃぁ無いと思うんだがなぁ。
3人しか使わなければバッドノウハウ。100人使えばグッドノウハウ。
現実のコンピュータ・チップ上でLISPを走らせるのは、中国語をしゃべれない友達に中国語トラベル辞典を使って中国語で手紙を書き、手紙といっしょにそのトラベル辞典を郵送するようなもの。本物のマシンでLISPプログラムを走らせるのは、一秒に数十億回のそういう余分な計算でCPUを無駄使いすることを意味する。
というわけで、遠藤さんに教えてもらったルディ・ラッカーの「ハッカーと蟻」読了。
いろいろと読みづらかった。
でも、いろいろと面白かった。
出てくる企業の名前とか、固有名詞が生々しい。
しかし、フィードバック系の描写があまりにあまりなような気がする。
bot: googlec: error occurred(18200), error is occurred(8)
ガーン。
require 'cgi' module HtmlParts # tree ::= string # | [:symbol tree] # def tree2string tree case tree when String CGI.escape(tree) when Array sym = tree.shift attr = '' elems = tree.map{|e| if e.kind_of?(Hash) e.each{|k, v| attr += " #{k}='#{v}'" } '' else tree2string(e) end }.join "<#{sym}#{attr}\n>#{elems}</#{sym}>" else raise "unknown tree" end end # PARTS_1 = %w{ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT TEXTAREA FORM A BLOCKQUOTE CAPTION } PARTS_2 = %w{ IMG BASE BR AREA LINK PARAM HR INPUT COL META } PARTS_3 = %w{ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY COLGROUP TR TH TD HEAD } (PARTS_1 + PARTS_2 + PARTS_3).each{|e| elem = e.downcase eval <<-EOS def _#{elem} *args [:#{elem}].concat(args) end EOS } end include HtmlParts puts tree2string( _html( _head( _title('hogehoge')), _body( _h1('huga-'), _p('hogehoge', _a('href' => 'dokka'), 'huga'))) ) #=> <html ><head ><title >hogehoge</title></head><body ><h1 >huga-</h1><p >hogehoge<a href='dokka' ></a>huga</p></body></html>
やっぱりイマイチかも。カンマがウザスギ。
class FindNumber < BaseEntry include HtmlParts def initialize *args super @ans = 50 @history = [] end def e_ *args e_start(*args) end def page ttl, *body page =_html( _head(_title('Find Number: ' + ttl)), _body( _h1(ttl), *body)) p page tree2string(page) end def form _form_cont(:guess, _input({'type' => 'text' , 'name' => 'number'}), _input({'type' => 'submit'})) end def history _ul( *@history.map{|e| _li(e.to_s) }) end def e_start *args page('start', form) end def e_guess n, = @req['number'].to_i @history << n if n == @ans hit else miss n end end def hit page('hit', _p("Hit! Answer is #{@ans}"), history) end def miss n if n < @ans mes = 'higher' else mes = 'lower' end p mes page('miss', _p(mes), history, form) end end
懲りずに数あて。
うーーーーんーーーー。
cgi にも pstore 使って突っ込めばいいやー、とか安直に考えてたら、id がダメダメだ。
なんとかの唄終了。グロ。
短くていい。でも、なんとか街よりは、マシ。
こんな時間までダラダラしてしまったが、明日、というか今日は本学入試らしいので入れない、というか出れなくなるらしいので泊まれない。帰ろう。
よくある風景。
cont = nil open('t', 'w'){|f| callcc{|c| cont = c } f.puts 'hello' } cont.call
big!age 終わり。長すぎ。
そういえば、情報処理学会全国大会のことスッカリ忘れてた。もぐりこもう見に行こうかと思ってたのに。
全大は、時間の無駄、と思って行く気もなかった…
研究室のミニ掃除。
/nantoka.cgi/ClassName/method
なやつで、ClassName.new.method
を呼び出してみるとどうだろう。
なかなか便利じゃないだろうか。
で、new した奴は継続とかその辺に使う、とか。継続情報は id になるんかな。ああ、いいかもしんない。実装してみよう。
cgi だけじゃ継続だめってことをさくっと忘れていた。さて、裏で何を動かすか。
まだ掃除。なんかずーーーーーっとやってる気がする。他の奴はあまり来ないし。
Webrick自体がそんな感じか。
expireが出来ないかな、これだと。
require 'webrick' include WEBrick class ContManager class ContItem def initialize obj @obj = obj @ctime = Time.new end def invoke *args @obj.call(*args) end end def initialize @cont_set = Hash.new @entry_set= Hash.new end def regist_cont obj ci = ContItem.new(obj) @cont_set[ci.object_id] = ci ci.object_id end def regist_entry klass @entry_set[klass.name] = klass end def expire end def dispatch_entry klass, args entry = @entry_set.fetch klass if args.size == 0 entry.new.default(*args) else entry.new.__send__(*args) end end def dispatch_cont cont, *args cont = @cont_set.fetch cont.to_i cont.invoke args end end ContManagerInstance = ContManager.new class AbstractEntry def self.inherited subclass ContManagerInstance.regist_entry subclass end def default "<html>error</html>" end end class TestEntry < AbstractEntry def default *args p args "<html> test entry default </html>" end def hoge *args p args "<html> test entry hoge! </html>" end end class Contlet < HTTPServlet::AbstractServlet def do_GET req, res p req.path_info cont_info = req.path_info.split("/") cont_info.shift p cont_info res.body = dispatch(*cont_info) end def dispatch klass, *args if /cont-(.+)/ =~ klass # cont ContManagerInstance.dispatch_cont $1, args else # static entry class ContManagerInstance.dispatch_entry klass, args end end ## alias do_POST do_GET end s = HTTPServer.new( :Port => 2004, :DocumentRoot => Dir::pwd + "", :CGIPathEnv => '/bin:/usr/bin:/usr/local/bin', :Logger => WEBrick::Log.new(nil, WEBrick::Log::DEBUG) ) s.mount("/cont", Contlet) trap("INT"){ s.shutdown } s.start
私が考えられることだから、誰でも考えるんだろうけれど、楽でイイね。
サンプルがいい加減なのはいつもどおり。さて、継続、継続。
Proc で継続すんのか、object だけで継続すんのか。はて、どうしたもんかな。
さて、dispatch の責任はどっちが持つべきだろう。うーん。
やりなおし。
require 'webrick' include WEBrick class ContManager class ContItem def initialize obj @obj = obj @ctime = Time.new end def invoke req, args @obj.req = req if @obj.respond_to? :call @obj.call(*args) else @obj.send(*args) end end end def initialize @cont_set = Hash.new @entry_set= Hash.new @default_entry = "AbstractEntry" end def regist_cont obj ci = ContItem.new(obj) @cont_set[ci.object_id] = ci ci.object_id end def regist_entry klass @entry_set[klass.name] = klass end def expire end def dispatch req, klass, args if klass == nil klass = @default_entry end begin if /c-(.+)/ =~ klass dispatch_obj req, $1, args else dispatch_entry req, klass, args end rescue IndexError "<html><body>error, no such entry or continuation: #{klass}</body></html>" end end def dispatch_entry req, klass, args entry = @entry_set.fetch klass if args.size == 0 entry.new(req).default(*args) else entry.new(req).__send__(*args) end end def dispatch_cont req, cont, args prc = @cont_set.fetch cont.to_i prc.invoke req, args end end ContManagerInstance = ContManager.new class AbstractEntry ContManagerInstance.regist_entry self def initialize req @req = req end def self.inherited subclass ContManagerInstance.regist_entry subclass end def default "<html>default default entry</html>" end end class TestEntry < AbstractEntry def default *args p args "<html> test entry default </html>" end def hoge *args p args "<html> test entry hoge! </html>" end end class Contlet < HTTPServlet::AbstractServlet def do_GET req, res cont_info = req.path_info.split("/") cont_info.shift klass = cont_info.shift res.body = ContManagerInstance.dispatch(req, klass, cont_info) end alias do_POST do_GET end s = HTTPServer.new( :Port => 2004, :DocumentRoot => Dir::pwd + "", :CGIPathEnv => '/bin:/usr/bin:/usr/local/bin', :Logger => WEBrick::Log.new(nil, WEBrick::Log::DEBUG) ) s.mount("/cont", Contlet) trap("INT"){ s.shutdown } s.start
未だに全然WEBrick がわからないのでてきとー。
require 'thread' class ContManager ExpiredTime = 60 * 30 # 30 sec class ContItem def initialize obj @obj = obj @ctime = Time.new end def invoke req, args @obj.req = req if @obj.respond_to? :call @obj.call(*args) else @obj.send(*args) end end def expired? Time.now - ExpiredTime > @ctime ? true : false end end def initialize @cont_set = Hash.new @entry_set= Hash.new @cs_lock = Mutex.new @default_entry = "AbstractEntry" end def regist_cont obj ci = ContItem.new(obj) @cs_lock.synchronize{ @cont_set[ci.object_id] = ci } ci.object_id end def regist_entry klass @entry_set[klass.name] = klass end def get_cont key begin @cs_lock.synchronize{ @cont_set.fetch key } rescue IndexError raise "No such entry or continuation: #{klass}" end end def expire @cs_lock.synchronize{ @cont_set.each{|k,v| if v.expired? # expired @cont_set.delete k end } } end def dispatch req, klass, args if klass == nil klass = @default_entry end begin if /c-(.+)/ =~ klass dispatch_obj req, $1, args else dispatch_entry req, klass, args end rescue => e "<html><body><h1>Error is occured</h1><p>Error #{e.message}</p></body></html>" end end def dispatch_entry req, klass, args entry = @entry_set.fetch klass if args.size == 0 entry.new(req).default(*args) else entry.new(req).__send__(*args) end end def dispatch_cont req, cont, args prc = get_cont cont.to_i prc.invoke req, args end end ContManagerInstance = ContManager.new class AbstractEntry ContManagerInstance.regist_entry self def initialize req @req = req end def self.inherited subclass ContManagerInstance.regist_entry subclass end def default "<html>default default entry</html>" end end class TestEntry < AbstractEntry def default *args p args "<html> test entry default </html>" end def hoge *args p args "<html> test entry hoge! </html>" end end ################################################################## ## depend on webrick require 'webrick' include WEBrick class Contlet < HTTPServlet::AbstractServlet def do_GET req, res cont_info = req.path_info.split("/") cont_info.shift klass = cont_info.shift res.body = ContManagerInstance.dispatch(req, klass, cont_info) end alias do_POST do_GET end s = HTTPServer.new( :Port => 2004, :DocumentRoot => Dir::pwd + "", :CGIPathEnv => '/bin:/usr/bin:/usr/local/bin', :Logger => WEBrick::Log.new(nil, WEBrick::Log::DEBUG) ) s.mount("/cont", Contlet) trap("INT"){ s.shutdown } s.start
肝心なところを書いてない。
module HtmlParts # tree ::= string # | [:symbol tree] # def tree2string tree case tree when String tree when Array sym = tree.shift attr = '' elems = tree.map{|e| if e.kind_of?(Array) && e[0] == :_ e[1..-1].each{|a| attr += " #{a[0]}='#{a[1]}'" } '' else tree2string(e) end }.join "<#{sym}#{attr}\n>#{elems}</#{sym}>" else raise "unknown tree" end end def t_html(*elems) [:html].concat elems end def t_body(*elems) [:body].concat elems end def t_title(ttl) [:title, ttl] end def t_p(*elems) [:p].concat elems end def t_acont(cont, *elems) [:a, [:_, ["href", "c-#{cont.object_id}"]]].concat elems end end include HtmlParts def page ttl, *elems tree2string( t_html( t_title(ttl), t_body(*elems))) end puts page("hello!", t_p("Hello! ", t_acont(lambda{ page("Hello2!", t_p("Hello2!")) }, "-next-")))
急ごしらえで SXMLもどきを書いてみた。
やっぱダメっぽい。果てしなく気色悪い。
ERb に細工するなり、そういうのを考えたほうがヨイっぽ。
しかし、: なり @ なり / なり使えないのは不便だなぁ。
出来た。
module HtmlParts # tree ::= string # | [:symbol tree] # def tree2string tree case tree when String tree when Array sym = tree.shift attr = '' elems = tree.map{|e| if e.kind_of?(Array) && e[0] == :_ e[1..-1].each{|a| attr += " #{a[0]}='#{a[1]}'" } '' else tree2string(e) end }.join "<#{sym}#{attr}\n>#{elems}</#{sym}>" else raise "unknown tree" end end def t_html(*elems) [:html].concat elems end def t_body(*elems) [:body].concat elems end def t_title(ttl) [:title, ttl] end def t_p(*elems) [:p].concat elems end end require 'thread' class ContManager ExpiredTime = 60 * 30 # 30 sec class ContItem def initialize obj @obj = obj @ctime = Time.new end def invoke req, args if @obj.respond_to? :call eval("self", @obj.binding).req = req @obj.call(*args) else @obj.req = req @obj.send(*args) end end def expired? Time.now - ExpiredTime > @ctime ? true : false end end def initialize @cont_set = Hash.new @entry_set= Hash.new @cs_lock = Mutex.new @default_entry = "AbstractEntry" end def regist_cont obj ci = ContItem.new(obj) @cs_lock.synchronize{ @cont_set[ci.object_id] = ci } ci.object_id end def regist_entry klass @entry_set[klass.name] = klass end def get_cont key begin @cs_lock.synchronize{ @cont_set.fetch key } rescue IndexError raise "No such entry or continuation: #{key}" end end def expire @cs_lock.synchronize{ @cont_set.each{|k,v| if v.expired? # expired @cont_set.delete k end } } end def dispatch req, klass, args if klass == nil klass = @default_entry end begin if /c-(.+)/ =~ klass dispatch_cont req, $1, args else dispatch_entry req, klass, args end rescue => e "<html><body><h1>Error is occured</h1>" + "<p>Error #{e.message}</p><pre>#{e.backtrace.join("\n") }</pre></body></html>" end end def dispatch_entry req, klass, args entry = @entry_set.fetch klass if args.size == 0 entry.new(req).default(*args) else entry.new(req).__send__(*args) end end def dispatch_cont req, cont, args prc = get_cont cont.to_i prc.invoke req, args end end ContManagerInstance = ContManager.new class AbstractEntry ContManagerInstance.regist_entry self include HtmlParts def initialize req @req = req end attr_accessor :req def self.inherited subclass ContManagerInstance.regist_entry subclass end def default "<html>default default entry</html>" end def t_acont(cont, *elems) id = ContManagerInstance.regist_cont cont [:a, [:_, ["href", "/cont/c-#{id}"]]].concat elems end end class TestEntry < AbstractEntry def default *args "<html> test entry default </html>" end def hoge *args "<html> test entry hoge! </html>" end def page ttl, *elems tree2string( t_html( t_title(ttl), t_body(*elems))) end def hello page("hello!", t_p("Hello! ", t_acont(lambda{ page("Hello2!", t_p("Hello2!")) }, "-next-"))) end end ################################################################## ## depend on webrick require 'webrick' include WEBrick class Contlet < HTTPServlet::AbstractServlet def do_GET req, res cont_info = req.path_info.split("/") cont_info.shift klass = cont_info.shift res.body = ContManagerInstance.dispatch(req, klass, cont_info) end alias do_POST do_GET end s = HTTPServer.new( :Port => 2004, :DocumentRoot => Dir::pwd + "", :CGIPathEnv => '/bin:/usr/bin:/usr/local/bin', :Logger => WEBrick::Log.new(nil, WEBrick::Log::DEBUG) ) s.mount("/cont", Contlet) trap("INT"){ s.shutdown } s.start
いやー、やっぱ webrick 使うと楽だなぁ。
でも、SXMLもどきはダメダメなことを知る。
lambda でグチャグチャやるのもやっぱり ruby らしくないよなぁ。うーむ。
Object が引き回せても、そんなもん session でやれヨ、とか言われそう。すみません。
その言語によるページと継続の自然な表現が問題になるんだろう。多分。
やっぱり ERb との連携・・・。
ruby でCPS って言うのも・・・。
ERb でやってみた。
class TestEntry < AbstractEntry def erbpage ttl, elems ERB.new(<<EOS).result(binding) <html> <head> <title><%= ttl %></title> </head> <body> <h1> <%= ttl %> </h1> <p>Hello!</p> <p> <%= elems %> </p> </body> </html> EOS end def helloERb erbpage('hello1', acont( lambda{ erbpage('hello2', 'hogehoge') }, "next" ) ) end def acont cont, name id = ContManagerInstance.regist_cont cont "<a href='/cont/c-#{id}'>#{name}</a>" end end
うーん・・・。失敗の予感。
eRubyスクリプト中に continuation を処理する奴を書くべきなのか。
occur は自動詞だと思う今日この頃....
確定申告してくる。どうやら、4時ごろに行ったのがよかったのか、意外に空いていた。
ウェブアプリケーションサーバを考えるとき、多分その言語でもっとも自然に扱えるものと URI というか PATH_INFO を結びつけるのが賢いやり方になるだろうか。Zope(Python) ではオブジェクト、kなんとかでは closure。Struts(Java) ではXML(ぉ。
じゃぁ、Ruby では?
修論の直しを終わらせる。さっさと帰ろう。
本日2日目の無料納税相談、無事終了。疲労困ぱい。申告は3月15日まで、お早めに。
おお、お疲れ様です。繁忙期ですね。
QUERY_STIRINGよりもPATH_INFOの方が使えるんだよねぇ。PATH_INFOをメソッド名とすると良い感じ。 そしてどうせ受領印だけの確定申告なんて時間外文書収受箱に入れるのが一番です。
トップに出すのは最新コメントじゃなく最新本文じゃない? と最新を上にするために書き込んでみるテスト。
やっと新・〜が終わった。ながかった。最後の最後、びっくり。
あかん、何もやる気がでない期間に入ってしまった。マズー。
業務連絡→ささP:また落ちてたので、このマシンの電源ユニット交換したぴょん。今日は会議攻めなんでこれがやっとだぴょん(夜も埋まってる…)
あれ,電源そんなに死にまくりですか? やっぱ工事停電のときは電源ケーブル抜いておいた方が良いんでしょうか・・・?
単に経年による劣化が偶然重なったらしい(あと数週間でマシン交換だと言うのに)。それはそれとして、UPS入れないなら工事停電はケーブルぬくべし。せめてサージ吸収タップ入れるとか。
Scheme の処理系を実装する人は、何度も作り変えてしまうので、やっぱりダメなんじゃないでしょうか。
ウェブサーバの電源系が不調だったようなのですが、いつのまにかなおってる。どうやったんだろう。
自宅もpivot にしてみた。
Totally Sidetalkin' Nokia N-Gage Style!! SIDETALKING 2003。よくわからないけど、爆笑してしまった。
最近 Ruby を触っていない。とても不味い。Rubyが読めなくなってる。Rubyが書けなくなってる。Rubyの話題についていけなくなってる。
今回の投票「メールの返信にかかる時間は?」ってのも、ビジネスマナーとかなんとかあるよね。
本当は、アドレス帳になんて登録しますか、にしようかと思ったんだけど流行りも過ぎたし、うんこと書くのは嫌だったのでやめた。
Ruby で HTMLというか、構造化した文章構造を表現する方法は何があるか。
[:body [:h1 "title"] [:p "hogehoge"]]
とかSXMLもどきは、なんとなく嫌な感じ。(見え方、性能の点で)
でも、REXMLみたいにするのはもっと面倒くさい。
んー。
Treeを表現するプリミティブが無いのかな、やっぱり。
class作れよとかありそうだけど、リテラルとして表現できないのは、なんというか、面倒。
構文要素がメソッドだったら。
body( h1("title") p("hogehoge"))
cgi ってこんな感じだったよね、たしか。
これが一番正解か。でも、出力は配列な気がする。面白くないなぁ。
コンテキストがどうなるかってのが問題になるな。うーん。
アトリビュートをどうやって表現するか。
a(attr("href", "http://..."), "nantoka")
うーん。微妙。キーワード引数欲しいね。
RGSSっていうんですか、IRCで聞いてたんですが、あれだよね。見せかけが似てるってだけだよね。Rubyみたいな変態的ないろいろと考えてある言語を再実装するって大変だよね。
私も、言語機能を縮小したバージョンを作ってみたいとは思ってはいるんですが。とりあえず parser 書くの楽な奴。
クリンゴン語と聞くとグロンギ語を思い浮かべる私はどちらもよく知らない。
単に電源ユニット取り替えただけよぴょーん
最初に「細砲」と訳した,っつったって,社会主義運動が世界に広まった頃だから大戦期ですがな
だから、そのときの訳が。自由とかと違ってアレじゃん。
『Rubyの話題についていけなくなってる。』 ← では最新の話題ということで RGSS について何かひとこと.
「構文要素をメソッドにする」でいいんじゃないですか。それをインタフェースにしといて、実際に配列が出来るか文字列にべたで出すか出力せずに検索をかけるか、それは実装クラスをすげかえればいいわけですから。
やっぱりそれが綺麗ですかね。instance_eval でも使わないと綺麗に出来ないかもしれないけど。
日本で「細胞」という言葉が使われだしたのは1920年前後でしょうね。ロシア語からの訳かドイツ語かイタリア語かわからんけど(最初は多分、青年イタリア党とかナロードニキとか)。で、「細胞」の何が嫌なのかわかりません。まさか生物学用語としてしか使っちゃいかんとか?
「胞」という字のニュアンスが、その単語に使われるのがどうもなじめません。
(「字源」角川書店 より)
にくづきなので、どうにも人の集合という意味には取りづらく。私だけかもしれませんが。
しかし、月偏を探してぜんぜん見つけられなかった。やれやれ。もう漢字読めない。
cellにも「人の集合」と言う意味はないと思いますが。ようするに「小部屋」でしょう。
cell にその意味があるのはそうなのだと思います(語源をしっかり見つけられなかったのですが)。ですが、その意味のまま細胞と持っていくのはどうなのかな、と思いました。
CGIの大事なこと。print "Content-type: text/html; charset=shift_jis\n\n"; by perl。いや,何か違う気がしますが。(まじめに言えばTemplate-Toolkit万歳。)
液晶が着たんだけど色がしょぼい。デジタル入力とかいうのを試してみたかっただけというのもあるんだが。
色温度とか変えられないしなぁ。
タンスターフル!
というわけで、ハインラインの「月は無慈悲な夜の女王」読了。面白かったけど、どの辺が夜で無慈悲で女王だったのかよくわからなかった。月は厳しい女教師ならわかるなぁ。
訳、ミスが結構あったような。細胞ってのはダメなんじゃないかなぁ。cell かな。なんだろ。セルのまま、とか。
最後の一文、よくわからなかったな。
基本的にサクセスストーリーというか、ああ、こうなるんだ、ハッピーエンドなんだね、って途中、しかも結構前半でわかるもんだから、安心して読めたのかもしれないな。
ちなみにプリズマ、私はやってるのをちらっと見ただけで、何も知りません。
しかし、10歳の女の子に依存する主人公もアレだが、10歳で結婚を思いつめる女の子も凄いな。
結婚してるのを知ったとき、主人公はその相手の名前を見たんだろうか? 見て、この全貌がわかったのか、絶望して、時間旅行したのか。ここだけ、よくわからない。
えーと、今週末は ruby-dev 投稿禁止ってことで・・・。
irc で聞いたんですが、スズメバチ攻撃のミツバチに「覚悟」遺伝子。うわぁ。
トリビアご出演おめでとうございます。俺見てないから誰が出たのか知らんけど。いろいろと撮影状況とか聞きました。
今度、また教えてください。飲みながらでも(ぉ。
おつかれさまでございました。これでやっと難しいことを気にせずにcommitできるんですね(ぉ。
人を偽ンチのフリークか何かみたいに... ところで新しい BSD って DragonFly ? じゃないような.
偽ンチって何
一昨年、テクノ探偵団の撮影のとき、映れば、と言ったのに、出ないで後でじ〜っと見ていたヒト
トリビアの種の話は、番組を見た人から聞きました。農工大でやったとか。高性能計算の(って言っても整数演算だけど)楽しいアプリだなー、と。
あの説明は大嘘なんで鵜呑みにしないでください。
あの二人にはいずれPTTかプロシンでしゃべらない?ってそそのかしておきました
あのアルゴリズム、3月下呂のMPS研で話したらしいのですが、やっぱり、面白おかしく聞きたいな
SIGXFSZ なんて初めて見た。
で、17インチ CRT を捨てることになるんだが、どうやって捨てればいいのかわからない。どないしよ。
というか、今そのディスプレイ起動したら、普通に写っている。なんてこった。もう金払っちゃったぞ。
先日話題になっていた新しい BSD のディストリビューション、昨日開始か。やっぱりOSの研究室なんだから、ちゃんと調査しておかないとダメですか。そうですか。
しかし、写真痛い なんか凄いですね。
誰か投票のねたをください。
ウェアラブルPCキター。初めて見た。着けた。これ以上怪しい人になるのはアレだな。
今の機能で思いつくのは動画を見ることくらいだが、事故るだけだな、これは。
ネットワークに繋がらないのは痛い。つなげ方がわからなだけなんだが。WinCE3.0 が入っている。
AirH" なり、 Pin-compact なりがないと面白くないな。
うーん、ぶっとんだことしないと面白いことはできないか。なんかないかな・・・。
頑張って生協まで着けていく誘惑に打ち勝つ。
人と会話してるときに携帯触りだす奴と、これをずっと着けてる奴、どっちが失礼だろう。
晴れの舞台とは言うけど雨の舞台とはいわない。
tell me three times ってなんだろ・・・。
ハインライン「夏への扉」読了。ちょっとのつもりが全部読んでしまった。面白い。面白かった。
いやー。・・・。うん。
あの長ったらしい名前のゲーム(KMさんが大好きな)の書評の意味がやっとわかった。成なんとかの世界の猫はピートさんですか。そうですか。
しかし、丁寧な作りだなぁ。
http://www.eizo-support.co.jp/usersupport/index7.html
高いねえ、4000円もするんだ。
「晴れの舞台」の場合の「晴れ(ハレ)」の対義語は「褻(ケ)」ですね。「ケの舞台」とも言いませんが。
長ったらしい名前のゲームって、P17n?
数えてないから知らないけれど、多分それデス。さすが、よく知ってるなぁ。
さすがささだ先生だと思いますた。
ゲームの批評は書評とは言わないんじゃなかろうか
ゲームの中で書評をしてたんです。ロリコン野郎がどうのって。
いいなぁ、HOKKE・・・。
もちろん、北海道がいいなぁ、なのですが。
def keyword? word begin eval("#{word} = 5") rescue SyntaxError return true end false end p keyword?('raise') p keyword?('if') p keyword?('begin')
あんまり考えてないから抜けがありそうですが、こんなのダメですか。そうですか。
まずは適当に正規表現でチェックしてからおもむろになんとか、ですか。やれやれ。
ありゃりゃ、こりゃ早い者勝ちですか。
p keyword?('keyword?') #=> true
ガーン。? と ! のチェック加えればいいのかしらん。
ささださんの案は、すでに「キーワード判定」以外の何かになってはいますが、もとの要求定義には依然有効なソリューションかと思います。
そうだよねぇ。can_use_variable_name とかかな。
なるほど。いただきます!
てけとーにしか考えてないのでダメだったらすんません。
valid_variable_name?とか
そういえば未踏公募開始してたのね。どうしようかな。
家族が1liter x 5本で105円な超あやしいジュースを買ってくる。まずすぎ。これは飲めん・・・。
やっぱディスプレイが1台だと狭い。というわけで、SyncMaster 174T でも買うか。通販で買うか、店まで行って買うか。
lexer をイテレータにするのは正しいか。イテレータってn個前に戻るってやつがないんだよな。あると便利だと思う。実装したくないけど。
ファミコンカラーではじめる僕らのゲームボーイ。
いろいろやってやっと動いた。ゲーム機動かすのになんでこんなに苦労を・・・。
今日のコミック。
なんかジョゼさんの顔変わってないか。
うひ、哲太郎先生もぶろぐか。
プロシンとき、近山先生に「みんなで交換日記してんの?」と言われた。そう考えると、なんか微妙だ。
実は orkut で一人裏切り者が出れば、ざくざく spam が。
うぅ、今月もしょっぱなから帰れない。自分のダメさに辟易。
以下は Werbric 使った何かで POST したときの挙動。
うがーーーーーーー。
apache だと IE5.5 + Proxy では大丈夫。
なーぜーじゃーーー。
あまりにマイナーな組み合わせなので無視でいいや。多分。
雪ー。いやー。
コンピュータ科学者がめったに語らないこと を買ってみる。
人は熱しやすく冷め(覚め)やすい。
継続的な議論がいかに大切なことか、身にしみる。
ほとんどの言語を触ったことがあるという人が居た。
どうやら、ほとんどの人が知ってる言語ということだったらしい。
Scheme はほとんどの人が知っていると思うんだがどうか。ダメですか。
アンケートによると 34 票中「なにそれ」が 3 票なので 9 割以上の人は知っている ということになりますね :-)
殆ど知ってますね。
SMLよりははるかにメジャーですね。orkutコミュニティーのメンバ数で比べてもScheme220人に対してSML8人…ってなんじゃそりゃ。SMLマイナースギ。
www.orkut.com
apache-jamesのMatcher / Mailetってのが面白いですよ。
モーションキャプチャ+カトゥーンレンダリングでしょう。どの程度一般的に使われてるのかは知りませんが。
あ、Flashのことを指してるのかな。
レンダリングのほうです。ゲーム機で自然にいけるのがスゲーな、と。関係ないですけど、トゥーンレンダリングだと思ってたんですが、「カ」が付くと別物?
cartoon (英) の省略表現が toon では?
おぉ、なるほど。もしかして日本語?>トゥーン ・・・英語でざくざくひっかかるな。
ザンパイダーうろおぼえアタック =□○_
|x, *xs|
toon shadingでは? Iron Giantあたりで知りました。Appleseedの絵はすごいですよ。(話はともかく。)
CG 用語としてはシェーディングはレンダリングに含まれるように思われ.PS2 だとリアルタイムにそのタイプの描画をやったのは某メモ2とかゼノサーガあたりが最初でしたか? 任天堂だとゼルダ?
PS2の初期リリースソフトに1本あったはずです>セルシェーディング
TVDJ のことかー!! http://www.amazon.co.jp/exec/obidos/ASIN/B00005OVNS/
レンダリングというと広くなりすぎるので,toon shader, toon shadingというのだと思います(google countきぼん)。