Macのrubyのreadlineに不具合がある!?
今日、まつもとさんから次のメールがruby-devに投稿された。
まつもと ゆきひろです
次回のリリース前に解決しておかなければならない用件って一覧になっていましたっけ。redmineだと
[ruby-core:17472] [Ruby 1.8 - Bug #206] BigDecimal precision in divmod
[ruby-core:17500] [Ruby 1.8 - Bug #211] "wrong argument type" "expected Proc"
[ruby-core:17479] [Ruby 1.8 - Bug #212] Issues with Readline in Mac OS X
[ruby-core:17518] [Ruby 1.8 - Bug #216] Memory leaks in 1.8.6p230 and p238
[ruby-core:17523] [Ruby 1.8 - Bug #222] Issues with Date#<=>
[ruby-core:17491] [Ruby 1.8.7 - Bug #213] Different ERB behavior across versions
[ruby-core:17556] Another security issue
くらいですか? 直ってるものもあるのかな。
rubyspecはどうでしょう?
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/35355より
Macをつかっている僕としては、この中の以下が気になった。
[ruby-core:17479] [Ruby 1.8 - Bug #212] Issues with Readline in Mac OS X
そして、何かの助けができないかと考えた。
そういえば、たびたび前田さんからMacのrubyは、readlineがなんとかこうとかと聞いていた。何が良くないのかわからないけど、readlineを使ったアプリケーションを書きたいと思っており、しかもMacユーザなので、readlineについて調べてみることにした。
そして、ruby_1_8ブランチのext/readline/readline.cのコードを見てびっくりした。メンテナが前田さんではないですか!?どうりで詳しいわけですね。納得。
/* readline.c -- GNU Readline module
Copyright (C) 1997-2001 Shugo Maeda */
http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/ext/readline/readline.cより
早速、前田さんにMacのreadlineの何がまずいのか聞いてみた。
- 高尾: 前田さん、Macのreadlineって何がまずいのですか?
- 前田さん: MLを読んで。
了解です。今、MLの過去ログを読んでます。できれば、何が問題なのかをまとめてみます。(期待しないでください。)
追記
チケットの問題が再現するかどうか確認した。
Mac上のrubyで、configureのオプションに--enable-libeditを付与した版。OK。再現する。
ragdoll$ ~/local/bin/ruby18trunk -rreadline -e 'Readline::HISTORY.push("1", "2", "3"); Readline::HISTORY.each { |i| puts i }'
2
3
次はfinkのruby。GNU readlineなので、問題は再現しない。
ragdoll$ /sw/bin/ruby1.8 -rreadline -e 'Readline::HISTORY.push("1", "2", "3"); Readline::HISTORY.each { |i| puts i }'
1
2
3
準備はできた。
次はMLの過去ログを読みあさろう。
追記
Ruby 1.8のブランチ(2006/12/05)のext/readlineがNetBSD currentでコンパイ
ルできない場合があります。
(省略)
NetBSDのeditlineライブラリは、GNU readlineへの互換関数を
用意していますが、rl_filename_completion_function()はあるものの、
rl_username_completion_function()やrl_completion_matches()はありません。
(NetBSD 3.xまでは、rl_filename_completion_function()もありませんでした。)
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/30008より
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/4858より
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/4868で、コンパイルが通るようになる。
こんな話もあった。
今調べたところ、readline は locale に従って動きます。
ていうか setlocale を呼びます。
(省略)
なので、readline が生成する文字列は default external encoding ではなく、
locale encoding にするのが適切ではないでしょうか。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/32872より
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/25232で、readlineのtest中に*BSDでささる。
ruby-devだけを読んでいる。あと半分くらいか。眠い。
ふと気になって、ruby-1.8とruby-1.9のreadline.cを比較した。
Readline.input=、Readline.output=が追加されたくらいしか大きな変更はないように思う。
なんか、いっそのことGNU readlineのwrapperを使うのではなく、libeditのAPIを直接使うことにすればいいのではないだろうか、と思えてきた。環境によって実装をがらりと変えるのだ。(酔っているのでよく分からなくなってきた。)
今日はここまで。
追記(2008/07/05)
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/26217で、editlineのサーポートを行ったあと、テストに失敗する。libeditを使用する場合、環境によってはテストが通らないことがあるので、libeditを使用する場合はテストを実行しないように修正。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/24854に添付ライブラリのメンテナの一覧がある。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/24855にコミッターがメンテナンスしている添付ライブラリの一覧がある。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/14530より
Readline モジュールで入力待ちのときに
Ctrl-C すると末状態を復帰しない問題の対処です
以上。ruby-devの過去ログを「readline」で検索した結果、気になったメールを読みました。
しかし、「Macのrubyのreadlineに不具合がある!?」という件について、何が悪いのかよく分からなかった。ruby-coreやruby-talkも読まないと分からないのだろうか。これはあとでやろう。
次は、ext/readline/readline.cを読みながら、GNU readlineのAPIを調査し、Readlineモジュールの機能を把握しよう。そして、editlineで置き換えることができないかどうか調査しよう。
追記(2008/07/07)
RubyのReadlineクラスのリファレンスマニュアルを読んだ。Readlineクラスのインタフェースと使い方がわかった。
http://i.loveruby.net/svn/rubydoc/doctree/trunk/refm/api/src/readline.rd
このとき、readline.cのソースを読んだ。そこで、rdocのドキュメントがないことに気が付いた。みなさん、Rubyのプロジェクトに貢献するチャンスですよ。
今日はもうおしまい。次回は、ext/readline/readline.cを読みます。あと、GNU ReadlineとEditLineのドキュメントも読む予定です。両者のソースコードは読まないかもしれません。