Windows で Rails 開発をやってて rb-readline という gem に泣かされていた。これがためにコンソールが死んだり,ジェネレーターが死んだりしていた。
ところが,いつの間にか直ってた。
直ってると知らずにエラい目に遭い続けてきた。
同じ境遇の人がいるかもしれないので報告する。
rb-readline とそのバージョン
rb-readline が Rails において何の役割を果たす gem なのか分からないまま,新規の Rails プロジェクトで Gemfile に
group :development do
platforms :mingw, :mswin do
gem 'rb-readline', '~> 0.4.2'
end
end
といつも書いてきた。判で押したように。
なぜこれを書くようになったのか,今となっては思い出せない。なぜバージョン 0.4.2 なのかももはや分からない。
結論を先に言えば,rb-readline を 0.4.2 にしていたのがトラブルの元だった。
最新版の 0.5.3 にしたら問題は解消した。
以下,どんなトラブルで困っていたか,三つの事例を挙げる。
事例 1:カーソルキーで死ぬ問題
Ruby のバージョンは以下のとおり。
ruby 2.1.7p400 (2015-08-18 revision 51632) [i386-mingw32]
再現手順
まず
rails c
で Rails コンソールを起動。
おもむろにカーソルキーに触る。すると
rb-readline-0.4.2/lib/rbreadline.rb:4269
において
in `block in _rl_dispatch_subseq': invalid byte sequence in UTF-8 (ArgumentError)
が出ていた。Windows でデフォルトの文字コードが CP932(Windows 31J)であることに起因するバグだろう。
とにかく,さっき打ったコマンドをもう一度と思って [↑] を打っただけでコンソールが落ちるのだからたまらない。
分かっていても,ついクセで打ってしまうのだ。
事例 2:そもそもコンソールが起動しない問題
さっきは Ruby 2.1 だったが,こんどは
ruby 2.2.4p230 (2015-12-16 revision 53155) [i386-mingw32]
の場合。
再現手順
rails c
とやっただけで,
rb-readline-0.4.2/lib/rbreadline.rb:1864
において
in `_rl_get_screen_size': undefined method `split' for nil:NilClass (NoMethodError)
が出る。
原因
rbreadline.rb の該当箇所を見ると,
wr,wc = `stty size`.split(' ').map{|x| x.to_i}
と書いてある。stty
という端末の情報を表示する Unix コマンドから情報を得ているのだ。
Windows にそんなものは無い。
事例 3:ジェネレーターのコンフリクト確認で死ぬ問題
Ruby バージョンは事例 2 と同じ Ruby 2.2。
再現手順
適当な Rails プロジェクトを作っておいて,テキトーなコントローラーを
rails g controller hello world
として作り,同じ名前のコントローラーを
rails g controller hello ruby
として作ろうとする。
当然コンフリクトが発生するので,まず端末に
conflict app/controllers/hello_controller.rb
と表示される。次に,どうするかを訊いてくるはずなのだが,ここで事例 2 とまったく同じエラーが出て死ぬ。
解決
事例 1 はずいぶん前から悩みの種だった。
事例 2, 3 は Ruby 2.2 にしてからのような気がする。bcrypt が Ruby 2.2 に対応してくれなかった問題1で長らく Ruby 2.1 を使い続けていたから気づかなかったようだ。
既に書いたように,rb-readline のバージョンが古いのが問題であって,これを 0.5.3 にしたらすべて解消した。
うー,人生を無駄にした。
解決はしたが,そもそも rb-readline を Rails の Gemfile に本当に入れなきゃいけないのかとか,基本的なことが分かってないままだ。
-
Windows のみ。Windows 用バイナリーが Ruby 2.1 用までしか収録されてなかった問題。2016年3月に解消。 ↩