history

青木日記 RSS

<前月 | 最新 | 次月>

2006-05-02

ふつける

ふつけるですが、5 月の……えーっと、何日だったかな。 30 日だか 31 日だかに発売らしいです。

品定めたけど

ThinkPad X60 にしようと決めて実物まで見にいったが、どう考えても予算が足りない。 それにノートパソコンがなくても困らない。というわけで購入を断念した。 俺がマシンを買うのをあきらめるなんてめっちゃ珍しいな。

(08:49)

もう一息

一気にいろいろかたづいて楽になって来てはいるのだが、 まだ何となく慌ただしい。連休ですべてかたづくだろうか。

(09:07)

るびま

あ、やべ……。るびまの添削記事もあったんだ。 どう考えても 4 日以降だなあ。

今回の添削は Tropy なんだけども、例によってちょっと暴走しすぎて、 添削っていうか「Ruby でウェブアプリケーション書くぜオラオラー・第一部」 になりつつあるのが恐ろしいところだ。

(09:18)


2006-05-13

『ふつうのHaskellプログラミング』サポートページ

『ふつうのHaskellプログラミング』のサポートページを作りました。

http://i.loveruby.net/ja/stdhaskell/

でもって正式な発売日は 5 月 31 日です。 正確には 31 日「配本」なので、 店頭に並ぶのは 6 月 1 日か 2 日になると思います。

(08:38)


2006-05-14

vim6 で cindent を切る

vim で *.c を編集すると妙なオートインデント (cindent) がかかる。 .vimrc で set nocindent としても切れないので気になってたんだが、 ようやく調べた。次のようにすれば切れるらしい。

au! filetypedetect * *.c
au! filetypedetect * *.h

au! は autocmd! の略で autocmd (フックみたいなもの) を消す命令。 filetypedetect はフックの種類。 「*」はイベント (ファイルを開いたとか読んだとか) の種類。 「*.c」はフックするパターン。

どんなフックが登録されているか調べるには、 vim を起動してモードラインで「:au」と打つ。 これで登録されているフックが全部リストされる。 また、次のように「:au * *.c」と打つと「*.c」に限定して調べられる。

:au * *.c
--- Auto-Commands ---
filetypedetect  BufNewFile
    *.c       call <SID>FTlpc()
filetypedetect  BufRead
    *.c       call <SID>FTlpc()

ファイル「*.c」に対するフックは FTlpc() という関数らしい。 この関数は /usr/share/vim/vim63/filetype.vim にある。 関数名のプリフィクス「FT」が file type (たぶん filetype.vim で登録してるからだな) で、 lpc は C 言語に類似の言語名らしい。 LPC 言語も C 言語と同じく拡張子に *.c を使うのでまとめてフックを登録する。 関数 FPlpc() 内では、LPC の予約語があれば LPC モード、なければ C モードにする (その結果として set cindent になる)。

以上の調査結果から、cindent を止めるには、 「*.c」に対するフックを消せばいいとわかる。 最初は「:autocmd BufNewFile,BufRead *.c set nocindent」とやったら フックが上書きされるかなーと思ったんだが、 実際にやってみると、フックが追加されるだけで終わってしまった。 つまりフックは明示的に削除しなければいけない。 ここで vim のリファレンスを見て 「:autocmd! TYPE EVENT PATTERN」がフックを削除する命令だとわかった。 もう一回「:au * *.c」をよく見ると、 filetype.vim で使っている TYPE は filetypedetect だと出ている。 したがって、「*.c」に対するフックを削除する命令はこうだ。

au! filetypedetect * *.c

ここで、よくよく考えると、*.h に対してもやっぱりフックがかかっていることは想像に難くない。 そこで、覚えたばかりの :au コマンドで *.h も調べてみる。

:au * *.h
--- Auto-Commands ---
filetypedetect  BufNewFile
    *.h       if exists("c_syntax_for_h") | setf c | elseif exists("ch_syntax_fo
r_h") | setf ch | else | setf cpp | endif
filetypedetect  BufRead
    *.h       if exists("c_syntax_for_h") | setf c | elseif exists("ch_syntax_fo
r_h") | setf ch | else | setf cpp | endif

やっぱりなんか登録されているので、これも消す。

au! filetypedetect * *.h

以上をまとめた結果は以下の通り。

au! filetypedetect * *.c
au! filetypedetect * *.h

(20:45)

Ruby 内 DSL で BNF を書く

http://log.ttsky.net/article/17335736.html
http://log.ttsky.net/article/17364209.html

む、tdp4r が改良されている。 「|」で or が記述できたり、リストが「*0」とか「*1」で書けるのも便利そう。 しかし右辺の g. がちょっと邪魔かなあ。 左辺の「g.expr =」のときは別に構わないような気がするのだけど。

Ruby 内 DSL で BNF を書く、Racc 編 (1)

Racc でもどーにかしてみようかと思っていじりはじめたのだが、 前に書いた

Racc::Grammar.define {
  rule program,   expr
  rule expr,      '(', expr, ')'
  _               expr, '+', expr  do .... end
  _               expr, '-', expr  do .... end
  _               expr, '*', expr  do .... end
  _               expr, '/', expr  do .... end
  _               num
}

てのだと大文字で始まる記号が書けないことにいま気付いた。甘かった。

いや待てよ、const_missing を使えばいけるかなあ。 const_missingっていつ実装されたんだっけ。1.8 にはあるのか。 じゃあ const_missing でやってみよう。

~/c/racc % ruby racc-onthefly.rb
[:program, :expr]
[:expr, :expr, "+", :expr, #<Proc:0x00002a95ebbbc8@/home/aamine/racc-onthefly.rb:53>]
[:expr, :expr, "-", :expr, #<Proc:0x00002a95ebb808@/home/aamine/racc-onthefly.rb:54>]
[:expr, :expr, "*", :expr, #<Proc:0x00002a95ebb470@/home/aamine/racc-onthefly.rb:55>]
[:expr, :expr, "/", :expr, #<Proc:0x00002a95ebb0d8@/home/aamine/racc-onthefly.rb:56>]
[:expr, :NUM]

できるじゃん。

Ruby 内 DSL で BNF を書く、Racc 編 (2)

あとは {...} での問題か。 do...end じゃなくて {...} を使うとルールの最後の記号を文字列にできない。 つまり、

rule expr,  expr, '^'   {|x| p x }

と書くと SyntaxError になってしまう。 これをどうにかするには……。

1. 括弧をつける。

rule(expr,  expr, '^') {|x| p x }

いまひとつ。却下。

2. エスケープ (?)

rule  expr,   expr, terminal('^')   {|x| p x }

なんかわかりにくい。

3. エスケープ (?) その 2

rule  expr,   expr, __('^')   {|x| p x }

余計わかりにくいか。

4. エスケープ (?) その 3

rule  expr,   expr, char('^')   {|x| p x }

うーん……。まあ、これのがマシ?

5. エスケープ (?) その 4

rule  expr,   expr, C('^')   {|x| p x }

もうちょっとエスケープっぽくしてみた。

6. エスケープ (?) その 5

rule  expr,   expr, '^', __ {|x| p x }

……何にしても直感的でないことに違いはないのか?

7. Proc を明示的に生成してみる

rule  expr,   expr, '^', lambda {|x| p x }

うーん。

8. do...end を推奨してみる

rule  expr,   expr, '^'  do |x| p x end

やっぱり 1 行で書くときは {...} がいいなあ。

Ruby 内 DSL で BNF を書く、Racc 編 (3)

tdp4r の代入スタイルもいいなあ。

Racc::Grammar.define {|g|
  g.program = rule(expr)
  g.expr    = rule('(', expr, ')')
  g._       = rule(expr, '+', expr) {|x, _, y| x + y }
  g._       = rule(expr, '-', expr) {|x, _, y| x - y }
  g._       = rule(expr, '*', expr) {|x, _, y| x * y }
  g._       = rule(expr, '/', expr) {|x, _, y| x / y }
  g._       = rule(NUM)
}

rule が邪魔だ。

Ruby 内 DSL で BNF を書く、Racc 編 (4) 連接にメソッド呼び出しを使ってみる

Racc::Grammar.define {|g|
  g.program = expr
  g.expr    = char('(').expr.char(')')

即値が使いづらいことこのうえないなこれは。やめよう。

Ruby 内 DSL で BNF を書く、Racc 編 (5) がんばって or を使ってみる

g.expr    = rule('(', expr, ')') \
          | rule(expr, '+', expr) {|x, _, y| x + y }

書けないことはないが、バックスラッシュが邪魔くさい。

(23:14)

LazyLines を Windows で動かす

ああそうか、Windows のことなんて忘れてた。だるー。 コンパイルは ghc -cpp -DWIN32 だけで通るようになってるのだが、 ウェブサーバの設定がなあ。 つーか、こういうときは何を入れればいいんだろうね。 まさか読者全員が IIS 持ってるとも思えないし、 結局 Apache2 なのかな。

あー、ダルい。本当にダルい。 インストールと設定の説明書くのが一番嫌いだ。

ぐあー 80 番ポートが使われてるー。 まずったな、IIS が動いてるんだ。

えーと、Windows だと httpd.conf はどこにあるんだろう。 ……Program Files の下か。それでいいんだろうか。 UNIX で /usr/local/apache2/etc に置いてあるようなもの……なの……かなあ……。

DocumentRoot はどこだ。 これも Program Files の下か。いいのかなあーこれで。

ん? DocumentRoot じゃなくて UserDir を使ったほうがいいのかなあ。 Windows では……My Documents の下ね。 My Documents\My Website\ ……って、My が多すぎだろ。 めんどいから public_html に変えちまおう。

配置
 
C:\Documents and Settings\aamine\public_html\ll\index.cgi
C:\Documents and Settings\aamine\public_html\ll\default.css
C:\Documents and Settings\aamine\public_html\ll\config
C:\Documents and Settings\aamine\public_html\ll\var\
C:\Documents and Settings\aamine\public_html\ll\template\

これでいいのかな。

(例によって) 動かない。UserDir の設定をロードしてなかった。

まだ動かない。サーバをリスタートしてなかった。

まだ動かない。.htaccess 書くの忘れてた。

動いた。しかし Edit が変だ。HTML が途中で切れてるな。 なんとなく binmode 関係のような気がする。

hSetBinaryMode stdin True
hSetBinaryMode stdout True

を追加したらうまくいった。

嘘だった。セーブされてないじゃん。

ええ? 何だこれ。 データベースに書き込まれてないということは、 save に行ってすらいない?

わかった……。フォルダとファイルのパーミッションがないからだ。 なんてありがちな。手っ取り早く SYSTEM からフルコントロールにして解決。

……めんどくせー。

(02:17)

本日のツッコミ (全4件) [ツッコミを入れる]

ttate [実は、右辺はgがなくてもOKです。右辺でgをわざわざ書いたのは"g.foo"でgを前置したシンボルだと見てはどうかと思ったためです。]

青木 [なるほど。個人的には g. がないほうがより DSL ぽくて好きです。
ちなみに、tdp4r の 1.0.6 よりも新しい版ってどこかから入手できますか?
なんか RAA もエントリがなくなってるぽいし……。]

青木 [define がないのであれば、所属を明確にする意味で g. が
付いてたほうがいいような感じはしますね。
でも define { ... } があるなら必要なさそう。]

青木 [あっと、RubyForge にあったんですね。
いただきました。]


2006-05-15

Windows で LazyLines を動かす (2) exerb と WEBrick でウハウハ作戦

Apache を動かすのは面倒すぎる。 HTTP サーバを同梱してしまうことにした。 と言っても Haskell で書くのはダルいので、 Ruby で WEBrick を使って書き、exerb でバイナリ化する作戦。

えーっと、インストールして、レシピファイル作って、exerb、で OK?

~/c/stdhaskell/src/lazylines % mkexr server.rb
....
^C
~/c/stdhaskell/src/lazylines % exerb server.exr
~/c/stdhaskell/src/lazylines % ./server.exe
server.rb:3:in `require': No such file to load -- webrick (LoadError)
        from server.rb:3

ありゃ? なぜだろう。なぜかしら。

なんだか理由はよくわからないが、 Cygwin 版の Ruby を使ってるのがなんかまずいような気がしてきた。 これでは拡張ライブラリが使えないだろう。たぶん。 Windows 再インストール以来 VC++ でコンパイルしてないので、しよう。

nmake がネーヨ、とか (vcvars32.bat を実行するの忘れてた)、 bison がネーヨ、とか (Cygwin で実行してごまかす) 言われつつもコンパイル成功。

……しまったあああ! --prefix 付けるの忘れてた! コンパイルしなおしだ。

もいっかい exerb をやりなおす。

~/c/stdhaskell/src/lazylines % ruby-vc -rexerb/mkexr server.rb
....
^C
~/c/stdhaskell/src/lazylines % exerb-vc server.exr
~/c/stdhaskell/src/lazylines % ./server.exe
server.rb:3:in `require': No such file to load -- webrick (LoadError)
        from server.rb:3

あれ? まだだめか。 もっと小さいスクリプトで試してみると、 require が入った瞬間にだめになるようだ。なぜだろう。

根拠なく、コアが何か違うのかなーとか疑ってみる。 とりあえず Ruby 1.9 コアを自分で作ってみるか。 えーと、VC++ で…… .dsp を開けばいいのかな。違った。.dsw のほうだ。

あー、プロジェクトが古いから鬼車が入ってないな。ファイルを登録する。

regex.c はいらないっと。 ファイルを削除するには……削除するには……あれ? 削除できないのかな。 とりあえず「このファイルはコンパイルしない」をチェックしておこう。

あああ、今度は exerb.cpp で大量のエラーが。 winsock2.h でエラーが腐るほど出ているなあ。なんだこれ。 俺の当てにならない勘によると、#include 順による問題と見たー。 ファイル冒頭の

#include <windows.h>
#include <ruby.h>

を逆にしてみる。

通った。すげえな俺の勘。奇跡だ。 全ての *.cpp で ruby.h を先に #include するように変更。

今度はリンカでエラーが出るなあ。えーと、未解決シンボルが 58 個?

NtSyncProcess, SafeFree, Win32System, definekey, do_aspawn, do_spawn,
mark_hash, mark_tbl, pipe_exec, rb_big_rand, rb_frame_last_func,
rb_inspecting_p, rb_io_flags_mode, rb_obj_id_obsolete, rb_protect_inspect,
rb_values_at, re_mbctab, re_set_syntax, ruby__end__seen, ruby_class,
ruby_eval_tree_begin, ruby_in_compile, ruby_parser_stack_on_heap, ...

新しい Ruby に存在しないシンボルが全部しくじってるのかな。 どっかに古いシンボルテーブルが残ってると見た。

どっか、どころじゃない。 src/exerb/*.def を全部アップデートしなきゃいけないんだ。 これ、いかにも自動で作れそうなんだけど、なんかルールがないのかな。

む。Ruby 本体に msvcrt-ruby19.def というのがあるな。 これを使えばよいのか? とりあえず素直にコピィしてみる。

おお! 未解決シンボルが 6 個に減った! これは単にファイル追加忘れっぽいな。 enumerator.c, ascii.c, euc-jp.c, sjis.c を追加。

2 つに減った。えーと今度は __imp__WSASocketA@24 と __imp__WSAEnumProtocolsA@12 がないらしい。 WinSock のインポートライブラリをリンクしろってことかなあ。 Ruby 本体もリンクしてたっけ?

……なんかしてるなあ。 ws2_32.lib というのがそれっぽい。 これをリンクすればいいのだろうか。

えーと VC++ でリンクするライブラリを追加するには……。 [プロジェクト]→[プロジェクトへ追加]→[ファイル] で C:\Program Files\Microsoft Visual Studio\VC98\Lib\WS2_32.LIB を追加か。

なんとなく通ったようだ。

あれれれ? できたファイルはどこにあるのー!

わかった。project/ruby190c/debug の下だ。 よし! 作ったばっかりの新コアを使ってみるぜー!

~/c/stdhaskell/src/lazylines % mkexr server.rb
....
^C
~/c/stdhaskell/src/lazylines % exerb server.exr -C ruby190c.exc
~/c/stdhaskell/src/lazylines % ./server.exe
server.rb:3:in `require': No such file to load -- webrick (LoadError)
        from server.rb:3

変わらねえ―――っ!

(次回に続く)

(05:24)

Windows で LazyLines を動かす (3) exerb 激闘編

いま突然気付いたッ! 天啓が来ました。 もしかてもしなくても、 exerb の require は独自実装なんじゃないか? っていうか、そうじゃないとおかしいだろ > 俺

ということは、eval.c を単純に上書きしてしまったからダメなのに違いない。 それじゃ最初はどうして失敗したのかなーとかいう疑問もわいてくるんだけど、 このさい弱気になるのは禁止風味で行くことにしよう。

exerb の eval.c を調査。

VALUE
rb_f_require(obj, fname)
    VALUE obj, fname;
{
    return exerb_require(fname);
}

やっぱりそうだ。require の中身が置き換わってる。 exerb-3.3.1/src/ruby-1.9.0/eval.c もこれと同じように書き換えてみる。

……まだだめだー。 やっぱりちゃんとした (?) バグなのか。 嫌だなあ。つくづく嫌だなあ。なんかめんどくさくなってきた。 Ruby のバイナリとかライブラリとか全部添付して済ませようかなあ。

しかし、何か変だな。ようするに、require を使ったときは、 exerb は最初っから最後まで動いてないわけだ。 いくらなんでもここまで変なら誰か気付くよなあ。 全然動かないってのは何か変だ。

あ……? わかつたー! たぶん $" に入るファイル名がフルパスになったからだ! そのせいで exerb_find_file_inside() がしくじってる。 ということは、もしかして、失敗するのは 1.9 限定?

やっぱり 1.8 は通るじゃん。うわーん。

(06:29)

Windows で LazyLines を動かす (4) exerb 死闘編

exerb を使ったときだけ WEBrick の CGI が動かねえ。

な、な、なんで…… ruby を popen してんだよおおお―――――!

うう、そりゃそうだ。 fork がないんだから popen するしかないか。 うわぁーん。

おにょれ、ここであきらめてたまるか……。 今度は webrick/httpservlet/cgi_runner.rb を exerb で実行ファイル化、 あーんど、webrick/httpservlet/cgihandler.rb をベタ書き換えだー。

~/c/stdhaskell/src/lazylines % ./server.exe
[2006-05-15 06:56:33] INFO  WEBrick 1.3.1
[2006-05-15 06:56:33] INFO  ruby 1.8.4 (2005-12-24) [i386-mswin32]
[2006-05-15 06:56:33] DEBUG TCPServer.new(0.0.0.0, 10080)
[2006-05-15 06:56:33] DEBUG WEBrick::HTTPServlet::FileHandler is mounted on /.
[2006-05-15 06:56:33] INFO  WEBrick::HTTPServer#start: pid=3100 port=10080
[2006-05-15 06:56:41] DEBUG accept: 127.0.0.1:1597
[2006-05-15 06:56:41] DEBUG WEBrick::HTTPServlet::FileHandler is invoked.
nocturne - - [15/May/2006:06:56:41    ] "GET / HTTP/1.1" 200 929
[2006-05-15 06:56:41] DEBUG WEBrick::HTTPServlet::FileHandler is invoked.
nocturne - - [15/May/2006:06:56:41    ] "GET /default.css HTTP/1.1" 304 0
[2006-05-15 06:56:49] DEBUG WEBrick::HTTPServlet::FileHandler is invoked.
nocturne - - [15/May/2006:06:56:49    ] "GET /?cmd=view;name=LazyLines HTTP/1.1" 200 930
[2006-05-15 06:56:57] DEBUG WEBrick::HTTPServlet::FileHandler is invoked.
nocturne - - [15/May/2006:06:56:57    ] "GET /?cmd=view;name=WikiClone HTTP/1.1" 200 842
[2006-05-15 06:57:02] DEBUG WEBrick::HTTPServlet::FileHandler is invoked.
nocturne - - [15/May/2006:06:57:02    ] "GET /?cmd=view;name=LazyLinesSyntax HTTP/1.1" 200 2507

よっしゃ動いたー! 完・全・勝・利!

(06:56)

LazyLines を Linux で動かす

しまったああああ! Linux より Windows のほうがインストールが楽になってしまった…… orz Linux ではバイナリは通用しないし、結局 Apache の設定を説明しなきゃいけないのか。 うざー。

なーんか面倒だし、ruby をインストールしてもらうことにしようかなあ。 それとも gcc は当然入ってるよねっ、 ということにして C でウェブサーバを書く (ふつりな再利用) か。 それすらも面倒だから Ruby のソースコードを まるごと入れといてコンパイル……とか……だめっすかね……。だめですね……。

(08:09)

LazyLines を Windows で動かす (終)

せっかく作ったので Windows 用 LazyLines バイナリ (+ HTTP サーバ) にリンク張っとく。

使いかた……ダウンロードして、解凍して、server.exe をダブルクリック。 同じホストのウェブブラウザから http://localhost:10081 にアクセス。終

(08:34)

LazyLines を Linux で動かす (2)

スタティックリンクした ruby を添付、という手はあるな。

sh で書いてある HTTP サーバを探す、とか (しかし改造するのがダルいなー)。

あとは…… C で書いた HTTP サーバをスタティックリンクする? なんかこれが一番楽そうな気がしてきたぞ。

続きは帰宅後。

(09:27)


2006-05-16

Mac Book

http://www.apple.com/jp/macbook/macbook.html

なにいいいいい! Core Duo な Mac Book が 13" にまで小さく! え、バッテリー 6 時間も保つの?! うわあ……。

でも「仕様の詳細…」のリンク先が 404 Not Found だよ! バカ! バカ! マック!

とりあえず、このままタブを残しておくと衝動的に 「購入する」ボタンを押しかねないのでタブ閉じ。

(03:48)


2006-05-18

ruby-dev summary

あっ! やっべ、ruby-dev summary 忘れてた。 隔週になっていらい、さらに忘れやすくなったな。

(05:26)

Ruby スクリプトを実行ファイル化する on Linux (1)

Linux で、Ruby スクリプトを単一実行ファイル化したい。 それもできるだけ汎用的な方法がいい。

[方針]

  • libc その他はすべてスタティックリンクする。
  • 拡張ライブラリもスタティックリンクする。
  • Ruby スクリプトは全部 objcopy でオブジェクトファイルにしてバイナリにリンクする。
  • require を Ruby レベルで差し替えてそっちを読ませる。

Ruby スクリプトを実行ファイル化する on Linux (2) ダイナミックロードの問題

ruby をスタティックリンクで作ると、 PAM でダイナミックロードされてるライブラリが使えない。ううーん。

……ん? 実は WEBrick では etc.so はほとんど使ってないのか。 UserDir オプションさえ使わなければ、 WEBrick に関してはとりあえず問題なさそうだな。 問題棚上げ。

他にダイナミックロードが必要と言えばネームサービスか。 サーバ側なら IP アドレスだけ使ってれば getaddrinfo は動かない……かな? なんかいけそうな気がしてきた。 これも問題棚上げ。

Ruby スクリプトを実行ファイル化する on Linux (3) どうやってプログラムを実行させるか

Ruby スクリプトは予定通り objcopy でオブジェクトファイルにして、 これを ruby とリンクさせる……まではよいのだが、 ruby にどうやってこのプログラムを実行させるかが問題だ。

ruby の main.c を差し替えてリコンパイルする方法だと、 ruby の objdir をずっと残しておかないといけない。 できれば ruby とか libruby-static.a だけを使ってどうにかしたい。

普通に ruby 組み込みインターフェイスを使ってしまうと、 拡張ライブラリがリンクされない (libruby-static.a しかリンクされないから)。 拡張ライブラリをスタティックリンクした libruby があるといいんだけどな。

libruby-static.a と拡張ライブラリの *.a を 全部まとめた、専用の libruby.a を自分で作ることにした。 これと独自の main.o をリンクしてバイナリを作る。 独自の main.c は ruby の main.c を基本とするが、 argv をすりかえてメインプログラムを -e でつっこむことにする。 なんかイマイチな方法だけど、まあとりあえず動きゃいい。

Ruby スクリプトを実行ファイル化する on Linux (4) require のすりかえ

さらに、main.c で次のように require をすりかえる。

extern struct script_source rb2exe_file_list[];
 
static VALUE
lookup_script(VALUE name)
{
    struct script_source *ent;
 
    for (ent = rb2exe_file_list; ent->name; ent++) {
        return rb_str_new(ent->start, ent->size);
    }
    return Qnil;
}
 
static void
replace_require(void)
{
    rb_define_global_function("_rb2exe_lookup_script", lookup_script, 1);
    rb_eval_string("\
        module Kernel                             \n\
          alias _rb2exe_original_require require  \n\
          remove_method :require                  \n\
          def require(feat)                       \n\
            rb = feat.sub(/\\.rb\\z/, '') + '.rb' \n\
            if src = _rb2exe_lookup_script(rb)    \n\
              eval src, ::TOPLEVEL_BINDING, rb    \n\
              $\".push rb                         \n\
              return true                         \n\
            end                                   \n\
            _rb2exe_original_require feat         \n\
          end                                     \n\
        end                                       \n\
    ");
}

rb2exe_file_list はリンク時にソースコードを自動生成してコンパイルする。

Ruby スクリプトを実行ファイル化する on Linux (5) 必要な *.rb の検出

残るは、require される *.rb を検出することだ。

……ちょっと考えたんだけど、必要なファイルだけじゃなくて、 ロードパスに入ってる *.rb は全部入れちゃうというのも一案かもしれない。 当然ながらバイナリはでかくなるけど、どーせオンデマンドロードなんだし、 いまどきバイナリが 10MB デカくなったところでたいした問題ではないのではなかろうか。

まあ、いちおう無駄を最小にする方向で考えてみよう。

exerb だと、実際に実行してみて require されるファイルを検出したりする。 しかし、これはいろいろな理由からできれば避けたい感じだ。 あと、レシピファイルを作るのはなんか面倒なので、 少なくともデフォルトにはしたくない。

なお、俺が前に作った簡単スクリプトでは、 単純にソースコードを require で grep して適当に検出していた。 動的な require さえなければこれでも結構うまくいく。

今回は、適当に grep する方針をデフォルトにしつつ、 残りの方法はオプションで選べるようにしようと思う。 つまり以下の四つを用意する。

  • ソースコードを再帰 grep して検出 (デフォルト)
  • 実際に実行して検出
  • 必要なファイルを明示的にリストする
  • ロードパスにある *.rb を全部つっこむ

(06:16)

ruby-dev summary (2)

ruby-dev summary を書くとき、具体的に何をやっているのか、 この日記に書き出してみようと思う。

まず、要約する範囲を決める。現在は隔週でやってるので、 前回の人が担当した部分のあとから二週間分くらいが目安となる。 前回は立石さんの [ruby-talk:190859] ruby-dev summary 28495-28605 なので、[ruby-dev:28606] から二週間くらい。 スレッドの切れめを考えると、[ruby-dev:28636] あたりまでかなあ。 ……って、30 通しかないのかよ。普通はもうちょっとあるんだけど。

対象範囲が決まったら、 新しいメールを作って Subject に範囲を書いてしまう。

次に、メールを眺めつつ、要約する必要のあるスレッドを抽出する。 「要約する必要のあるスレッド」とは、

  • Ruby の仕様や実装に関係する
  • 単に「バグ報告 → 修正」ではない
  • 議論がされている

という感じのスレッドを指す。今回の範囲ならば、次のようなあたり。 リストアップすると同時に、日本語の Subject はてきとうに英訳してしまう。

ちょっと減らしすぎた? というか、元となるメールが少なすぎるんだよ今回は。

ここまで来たら、あとは地道に一個ずつ要約して訳していく。

(次回に続く)

(07:57)

Mac Book 見てきた

店員が Mac Book を示してゐる。

大層大事さうに陳列棚に載せてゐる。
眠い目を擦り、いつたい何が入つてゐるのか見極めようとするが、如何にも眠かった。
Xeon か Opteron でも入つてゐるのか。
何とも手頃な善い匣である。
店員は時折笑つたりもする。

「ぽん」
匣の中から聲がした。
鈴でも轉がすようなシンセサイザーの聲だった。

……

……えー、まあ、京極ネタは置いといて。 実物見ると意外にのっぺりしてるのな。

(22:15)

もうだめ

ぎがねむす。今日はもう寝よう。

ああ、しかし、日記に適当なネタだけ書いて寝たりしてると、 ようやく本調子に戻ってきたかなと実感するね、印象があるね、そんな情勢だね (三段活用)。

(22:24)

本日のツッコミ (全4件) [ツッコミを入れる]

なかだ [const char *ptr = StringValuePtr(name);
long len = RSTRING(name)->len;
if (strlen(ent->name) == len && strncmp(ptr, ent->name, len) == 0)

あたりが抜けてると予想。]

MoonWolf [RubyScript2Exeとかはどうでしょうか?
Windows,Linux,MacOSXに対応しているようです。
http://www.erikveen.dds.nl/rubyscript2exe/index.html]

青木 [やっぱり眠いときにコードを書いちゃいけませんねえ。]

青木 [あ、何かあったなーと思ってたけど、RubyScript2Exe でしたか。
rb2exe はぐぐったんだけどなー。*.so までまとめてくれるんだなあ。
libc までは、なんとなく入れてくれないっぽい?
まあ、PAM とネームサービスの問題は解決方法が思いつかないしなあ。]


2006-05-19

一人でまったく新しいプログラミング言語を考えるスレ

ウィトゲンシュタインの『哲学的探求』読んでるときに考えついたんだけどね、 テストを書いとくとそれを満たすプログラムを生成してくれる言語ってどうよ。 つまり、テストを書くためだけのプログラミング言語。 そんなのできたら全世界の SE とコンサルが泣いて喜ぶね!

……そんなの実装できるわけねー。 ていうか全世界の SE の皆皆様が やってることはこの言語の処理系に近いような気がする。

(21:37)

一人でまったく新しいプログラミング言語を考えるスレ (2)

考えついてしまったからには名前を付けておかねばなるまい。 「SE 殲滅言語 version 1」の頭文字を取って「SSL/1」でどうだろう (無駄に紛らわしい)。

(21:42)

本日のツッコミ (全2件) [ツッコミを入れる]

kjana [帰納論理型言語をものすごく進化させたらそうなるか、みたいな。]

Average [カットの無いPrologはそういう言語の筈ですね。
論理型言語は(理論的には)双方向に動くので、論文からサマリーを抜き出すソフトを作ればサマリーから論文が出来る、だからみんな論理型言語に研究者は夢中になるのだ!
というのがProlog界隈での伝統的ギャクだそうです。

後、Prolog等の論理型言語だと、アルゴリズムデバッキングという技が使えるのでテストユニットも内蔵されているよーなモンです。

スクリプトとかに(今こそ)再評価されるべきでは<嘘度99%]


2006-05-20

Ruby スクリプトを実行ファイル化する on Linux (6) 完成

あー、どうも気が乗らねえなーっ

と思いつつダラダラと 8 時間くらいかけてようやく rb2exe ができた。動いた。 だがメインマシンは AMD64 なので、 公開用のバイナリを作るには i386 のマシンを起動しなければならない。ダルい。 そんなわけでまた寝る。

今日の RHG 読書会は久しぶりに出る予定。起きられれば。

(08:06)

本日のツッコミ (全2件) [ツッコミを入れる]

nobsun [起きた?]

青木 [いま起きました。
すんげー遅れましたがこれから行きます]


2006-05-22

一人でまったく新しいプログラミング言語を考えるスレ (3)

ツッコミをもらいました。ついでにリンク元からも。

http://alohakun.blog7.fc2.com/blog-entry-298.html

やっぱり論理型とかになるんですかねえ。 なんか無理そうだな、とわたしが思ったのは、例えば

assert(なんかすごいウェブサイトが存在する)

みたいなテストがあったら (書けちゃったら) どうすればいいのかなあと。 リストの追加みたいな細かい話ならできるってのはわかるんですが、 それだと結局プログラマが書かなきゃいけないコードの抽象度は変わらないような気がするんです。 SE 殲滅言語としては、すんごい曖昧なクライアントの要求にも応えられるくらい コードの抽象度が高くないといけないんじゃないかと思うのですよ。

うーん。実は単にライブラリを追加していけば済む話なのかなあ……。

(07:58)

Ruby スクリプトを実行ファイル化する on Linux (6)

rb2exe はだいたいできたんだけど、 喜び勇んでウェブサーバをバイナリ化したら即 SEGV した。 調査していくと、なぜか require 'socket' で dlopen が動いている。 なんでスタティックリンクされた拡張ライブラリをまた読みにいってるんだろう。

どうやら、ちゃんとスタティックリンクされてなかったようだ。 ext/extinit.o も ext/**/*.a もリンクされてない。 libruby.a を作り直して問題解消。

(08:14)

Ruby スクリプトを実行ファイル化する on Linux (7) ライブラリのリンクでエラー

ぜんぜん問題解消してなかった。 kerberos 他のライブラリがリンクされてないよー。

なんかいろいろ必要だなあ。 えーと、db-4.3, gdbm, ssl, crypto, krb5, krb5support, k5crypto, gssapi_krb5, resolv, com_err, readline, ncurses, termcap, util, pthread, z, m, c これで全部か? kerberos なんてどうせ使わないのになあ。 Fedora Core なんかで作るからこんなことになるんだ。 Debian で作ったほうが楽だったに違いない。

Ruby スクリプトを実行ファイル化する on Linux (8) digest/sha2 でエラー

うお、まだエラーが出てる。 ext/digest/sha5 のシンボルが libssl のシンボルと重複してる模様。なにい。 SHA512_Transform とか、なんかいかにも重なりそうだな。

うあー、そうか、もしかして ext/digest/sha2/sha2.c って libcrypto から持ってきてるのか。 そりゃ重なるに決まってる。

あれ? そういえば、openssl があるときは そっちを使ってたような気がしたんだけどな。 なんでそうならないんだろう。

うう、そうか、openssl を使うのは sha1 だけなのか。sha2 は違うのね。 きっと openssl のバージョンによって sha2 がサポートされてるとか されてないとか、そういうウザったい話があるのに違いない。

……違うな。重なってるのは SHA*_Transform だけだ。 ということは、これを static にしてしまえば済む話か。

(08:58)

Ruby スクリプトを実行ファイル化する on Linux (9) require の実装を間違う

おっかしーなー、定数を再定義してるぞって警告が出る。 どうも同じファイルを二回ロードしてるっぽいな。

……アホか俺は。 require の中で $" をチェックしてないじゃんか。

これで (rb2exe の問題は) 本当に解決したようだ。

(09:16)

LazyLines を Linux で動かす (3) rb2exe を使う

よーし使ってみよー。

…… またしても webrick/cgi_runner ではまる。 俺も進歩がないなあ。 えーと cgirunner.rb も rb2exe でバイナリ化ーと。

よし通った。

スタティックリンクな libc とカーネルバージョン

そういえば、AMD64 上でも動くのかな。 動くような気がするな。試してみよう。

~/c/stdhaskell/src/lazylines % uname -a                         aamine@serenade
Linux serenade 2.6.8-11-amd64-k8 #1 Wed Jun 1 01:03:08 CEST 2005 x86_64 GNU/Linux
~/c/stdhaskell/src/lazylines % ./server                         aamine@serenade
FATAL: kernel too old
zsh: 2491 segmentation fault (core dumped)  ./server

ぐは……。こうなるのか……。両方 2.6 なのになあ。 2.6.15 と 2.6.8 の違いだけでもうダメなのか。

え、待てよ、ということは、 スタティックリンクしててもカーネルが古いとだめってこと?! そんなの聞いてねー。

もしかして libc でカーネルのバージョンを明示的に指定してるのかなあ。 確かそんなオプションがあったような気がする。

別の AMD64 マシンでも試してみよう。

tukumo:~/c/stdhaskell/src/lazylines % uname -a                    aamine@tukumo
Linux tukumo 2.6.14-2-amd64-k8-smp #1 SMP Tue Nov 15 02:59:29 CET 2005 x86_64 GNU/Linux
tukumo:~/c/stdhaskell/src/lazylines % ./server                    aamine@tukumo
*****************************************************
           Type Ctrl-C to stop server
*****************************************************
[2006-05-22 09:30:33] INFO  WEBrick 1.3.1
[2006-05-22 09:30:33] INFO  ruby 1.9.0 (2006-05-18) [i686-linux]
[2006-05-22 09:30:33] DEBUG TCPServer.new(127.0.0.1, 10081)
[2006-05-22 09:30:33] DEBUG WEBrick::HTTPServlet::FileHandler is mounted on /.
[2006-05-22 09:30:33] INFO  WEBrick::HTTPServer#start: pid=11510 port=10081

なにー。こっちは動くじゃん。バージョンいくつから OK なんだよ。

(09:34)


2006-05-23

Word

MS Word でレポート書き。 6 ページほとんど全部箇条書きなのに、 箇条書きの挙動がわけわからなくて苦しむ。 ああー、でももう少しだ……。

メモリ 0xXXXXXX は "read" になれませんでした。終了します

[OK] [キャンセル]

死んでいいよ。

(10:14)

本日のツッコミ (全3件) [ツッコミを入れる]

teny [お察しします……]

arton [そう言えば最近めっきり死ななくなったので(Mac版で履歴表示しながら+Atokだとすぐ死ぬけど)、どのバージョンのWord +どのWindows? ちょっと興味あり。]

青木 [Windows 2000 SP4 に、確か Word 2000 だったと思います。
思い返してみると、Word はこれまでもよく落ちてるような……。]


2006-05-24