RubySpec を試して思ったこと。
Python の subprocess module は Ruby の open3 等に比べ、パイプラインの構成や communicate() など、より使い易い API に挑戦しているところが素晴らしいと思う。
cvs.m17n.org で apt-get upgrade する。
Debian の openssl の乱数生成の問題 があったが、cvs.m17n.org のホスト鍵は sarge 時代 (あるいはそれ以前) に生成したもので問題ない。ホスト鍵を変えると (ssh でアクセスしている) committer に影響がでるし変えないことにする。
あと、committer の公開鍵も検査したが問題があるものは見つからなかった。
しかし、手元の数台のマシンはホスト鍵に問題があって、それは対応の必要があった。
そういえば、今日は FSIJ の月例会である。今日の話は今年の Google SoCについて。
chkbuild で rubyspec を動かしてみた。
rubyspec は github で提供されているので git を使う。
動かすのはいいのだが、diff などの URL が問題である。
いままでの cvs/svn のスタイルでいけば、変更のあった各ファイルについて、前回から今回までの diff を示す URL をつけるのだが、github ではそういう diff を表示する URL が見つからない。
コミットを示す URL はあるので、直前のコミットを指す URL はつけておいたが、前回からの変更をうまく示しているわけではない。さらに、w3m では見えないのが感情を害する。
w3m で見えない件について調べてみた。
w3m を strace して、どんなリクエストを送っているか調べ、telnet で再現させる。
% telnet github.com 80 Trying 65.74.177.129... Connected to github.com. Escape character is '^]'. GET /brixen/mspec/commit/db61c605b52f6247d7098650b43662b743e6a4bc HTTP/1.0 User-Agent: w3m/0.5.1+cvs-1.968 Host: github.com Accept: text/*, image/*, application/*, audio/* Accept-Encoding: gzip, compress, bzip, bzip2, deflate Accept-Language: ja;q=1.0, en;q=0.5 HTTP/1.1 406 Not Acceptable Server: nginx/0.6.26 Date: Sat, 17 May 2008 15:26:51 GMT Content-Type: text/html; charset=utf-8 Connection: close Set-Cookie: _github_session=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7AA%253D%253D--05fe545aeb8e6719fb006b3a7474a1d3aeb228a4; path=/ Status: 406 Not Acceptable X-Runtime: 0.08184 Cache-Control: no-cache Content-Length: 1 Connection closed by foreign host.
あとはヘッダを削って原因を調べていくわけであるが、どうも Accept: が問題のようである。Accept: の先頭に text/html を追加したら見えるようになった。
いくらか考えた結果、git における変更はファイル単位でなくコミット単位で表示するほうがいい気がしてきたので、そうしてみる。
rubyspec は ruby とは別個に配布されている。
ruby 本体の make test や test-all が ruby に同梱されているのとは異なる。
この違いは興味深い結果をもたらす。
test-all 等が同梱されている ruby だけを対象とするのに対し、rubyspec はいろんなバージョンの ruby を対象とする。
つまり、意図して ruby の挙動が変化し、テストが失敗するようになったとき、test-all ではそれまでのテストを残す意味はない。新しい挙動に対するテストに修正することになる。
しかし、rubyspec では、新しい挙動にたいするテストを書くのはいいが、古いバージョンをどうあつかうかが問題になる。
古い ruby の挙動が、バグであるか仕様であるかを判断しなければならない。
バグであれば、正しい (新しい) 挙動のテストに書き換える。仕様であれば、古い仕様と新しい仕様のどちらをテストするかをバージョンで条件分岐する。
この判断がなかなか微妙なことがある。
たとえば 1.9 や 1.8.7 ではいろいろなイテレータで、ブロックを渡さないと enumerator を返すようになった。1.8.6 以前では、だいたい LocalJumpError であるが、そうでないこともある。例えば、[0].each は LocalJumpError で、[].each は [] を返す。
では、LocalJumpError だったり、[] を返していたのは仕様なのかバグなのか?
test-all であればその判断はしなくていいが、rubyspec ではしなければならない。なかなか難しいところである。
だいたい、新しい機能を導入するときは、使用頻度が低いところを狙うわけで、そんな使用頻度が低いところに共通認識があるかというと、かなり怪しいのではないだろうか。
ふと、Bloom Filter を調べてみる。ふむ、こういうものなのか。
[latest]