浦島太郎状態になっていたので、Ruby周りの文字コードの扱いについて改めて勉強しなおしました。簡単にいうとRuby 1.9.1以降の多言語化仕様(M17N)では、文字コードをどう扱えばよいのかという点です。
Rubyの文字コード変換ライブラリ
Ruby 1.9.1の多言語仕様化以前は、文字コードの変換には文字コード変換ライブラリを使用する方法が一般的でした。主な文字コード変換ライブラリは、次のようなものがあります。
- Kconv
- NKF
- Iconv
- Uconv
この中で、KconvはNKFのラッパーであり、NKFはnkf(Network Kanji code conversion Filte)をRubyから使うためのモジュールです。つまり実装としては、KconvとNKFの根の部分は同じです。またIconvは、UNIX95のiconv()関数のラッパーです。なお、IconvはRuby 1.9から非推奨、Ruby 2.0から標準添付ライブラリから削除されています。
Kconvの利用
Kconvを読み込むと、Stringクラスに次のメソッドが追加されます。
String#iseuc String#isjis String#issjis String#isutf8 String#kconv String#toeuc String#tojis String#tolocale String#tosjis String#toutf16 String#toutf32 String#toutf8
使い方としては、下記のとおりで手軽に使えて便利です。
require 'kconv' str = '日本語の文字コード' # 何らかの文字コードの文字列 puts str.toeuc # => ECUの文字コードに変換 puts str.tosjis # => Shift_JISの文字コードに変換 puts str.toutf8 # => UTF-8の文字コードに変換
一方で、Kconvについては幾つかの問題点があります。1つは、先述のとおりnkfライブラリを利用する為に、プラットフォーム依存が強いという点です。2つ目は、nkfライブラリの名前(Network Kanji code conversion Filte)が示すように、多言語化対応ではなく日本語対応のモジュールということです。この辺りの改善のために、Ruby 1.9からはM17Nを盛り込んだ仕様になっています。
追記:2014/04/08
nkfライブラリのプラットフォーム依存の話は、間違いでした。nkfのソース自体がRubyにインポートされて、ビルドされている模様です。モジュールを確認するとその通りでした。@yugui さんご指摘ありがとうございます。
$ tree nkf/ nkf/ ├── Makefile ├── depend ├── extconf.h ├── extconf.rb ├── lib │ └── kconv.rb ├── mkmf.log ├── nkf-utf8 │ ├── config.h │ ├── nkf.c │ ├── nkf.h │ ├── utf8tbl.c │ └── utf8tbl.h ├── nkf.c └── nkf.o
M17N対応
Ruby 1.9.1からは、M17N(Multilingualization)で多言語化の対応が根本的に変わっています。 Rubyの多言語化は、CSI(Code Set Independent)という方式を採用しています。これは他の言語の主流であるUCS Normalizationとは全く別の方式です。UCS Normalizationは、内部コードを特定の文字コード(多くの場合は、UTF)とし、入出力の際に別の文字コードが来た場合は変換して利用します。
これに対して、Rubyが採用したCSI方式は内部コードを持ちません。どの文字コードでも、そのエンコーディングに従い扱います。そのために、プログラム自身にエンコーディングを教える必要があります。Ruby 1.9でコード中にマルチバイト文字が出てきた場合に、Magic Commentが必要になったのはこのためです。
# coding: UTF-8 str = '日本語の文字コード' # 何らかの文字コードの文字列 puts str.encode("Shift_JIS") # => 暗黙的にUFT8から、Shift_JISに変換する puts str.encode("Shift_JIS","UTF-8") # => 明示的にUFT8から、Shift_JISに変換する
このString#encodeメソッドの実装は、class Encodingです。これは内部に文字コードの変換表を持っている訳ではなく、文字コードの取扱ルールを定義しているようです。またNKFのように日本語対応のみでなく、多言語対応です。
まとめ
ということで互換性の問題がなければ、String#encodeメソッドを利用しましょう。またちゃんと、Magic Commentを書きましょうね。(Ruby 2.0ではデフォルトがUTF-8になっているので、ほぼ不要とも言えますが。)
参照:
module NKF
library kconv
Rubyist Magazine - Ruby M17N の設計と実装
class String
class Encoding::Converter
多言語化
Rubyist Magazine - 標準添付ライブラリ紹介 【第 3 回】 Kconv/NKF/Iconv
404 Blog Not Found:ruby|perl - 文字コードのちょっと高度な判定
プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)
- 作者: 矢野啓介
- 出版社/メーカー: 技術評論社
- 発売日: 2010/02/18
- メディア: 単行本(ソフトカバー)
- 購入: 34人 クリック: 578回
- この商品を含むブログ (128件) を見る