2009/06/17

Recent entries from same category

  1. Ruby の Array#<< は Array#push よりも速いか
  2. Ruby の a = a + 1 はなぜ undefined method '+' for nil:NilClass なのか
  3. Re: Ruby 製バッチ処理を省メモリ化した
  4. Crystal と CRuby でHTTPサーバのベンチマーク
  5. pure mruby な JSON パーサ書いた。

使っているreadline.dllはここから持って来ているんだけど、まずこれがマルチバイトありでビルドされていない。なのでマルチバイト文字を入力した後、バックスペース押すと1バイト単位でしか戻らない。
今日はそれを解決してみる。readline-4.3-2-src.zipを持ってきて # unzip readline-4.3-2-src.zip
# cd readline-4.3-2¥win32¥shlib
# copy config.h config.h.orig
# vim config.h
diff -u config.h.orig config.h
--- config.h.orig   2003-04-14 16:04:46.000000000 +0900
+++ config.h    2009-06-17 17:04:07.234375000 +0900
@@ -128,11 +128,9 @@
 /* Define if you have the <varargs.h> header file.  */
 //#define HAVE_VARARGS_H 1
 
-/*
 #define HAVE_WCTYPE_H 1
 #define HAVE_WCHAR_H 1
 #define HAVE_MBSRTOWCS 1
-*/
 /* config.h.bot */
 /* modify settings or make new ones based on what autoconf tells us. */
 
# copy config.h ..
# mingw32-make -f GNUmakefile
とするとreadline.dllが出来上がるのでそれをパスの通った場所に置く。古いreadline.dllをバックアップしておいて入れ替えるのもOK。
次に、id:Constellationさんの記事にある以下のソースをlocale.cとして保存する。
#include <locale.h>
#include "ruby.h"

static VALUE mLocale;

static VALUE
locale_setlocale(obj)
{
  setlocale(LC_CTYPE, "");
#ifdef LC_MESSAGES
  setlocale(LC_MESSAGES, "");
#endif
  return Qnil;
}

void
Init_locale()
{
  mLocale = rb_define_module("Locale");
  rb_define_module_function(mLocale, "setlocale", locale_setlocale, 0);
}
そしてコンパイル # gcc -Ic:/ruby/lib/ruby/1.8/i386-mswin32 -shared -o locale.so locale.c libreadline.a c:/ruby/lib/msvcrt-ruby18.lib ワーニングが出るけど気にしない
出来上がったlocale.soを C:¥ruby¥lib¥ruby¥1.8¥locale.so として配置し、ホームディレクトリ(HOME環境変数を設定していないならばUSERPROFILE変数の位置)に".irbrc"というファイルを作って以下の様に書く。
begin
  require"locale"
  Locale.setlocale
rescue
end
require 'rubygems'
require 'utility_belt'
require 'win32console'
"utility_belt"はこの記事を、win32consoleはエスケープシーケンスを色付けして表示して貰うために...
後はirbを起動すれば、マルチバイト文字でバックスペースしても正しく1文字消えてくれます。

Constellation++

これでようやく、termtterでも正しく日本語が打てる。
なお、Constellationさんの記事にも書かれていますがtime.rb周りで弊害が出る可能性があるので、気を付けて。termtterの場合なら"~/termtter/config"にLocale.setlocaleを書いた方が良いかもしれない。
Posted at by