From: rubikitch@... Date: 2009-01-01T18:33:08+09:00 Subject: [ruby-list:45777] Re: Ruby 1.9.1-rc1[mswin32]でマルチバイトを含むソースが実行できない From: "Ayumu Aizawa" Subject: [ruby-list:45773] Re: Ruby 1.9.1-rc1[mswin32]でマルチバイトを含むソースが実行できない Date: Thu, 1 Jan 2009 17:43:20 +0900 > そして-Eex[:in]というオプションが追加されているみたいなのですが、これの使い方が > よくわからないです。 > > -Eex[:in] specify the default external and internal character encodings >  →規定の外部/内部エンコーディングを指定する これはdefault_externalとdefault_internalを設定します。 IOエンコーディングの設定なのでスクリプトエンコーディングを変更するわけではありません。 > ということみたいなのですが、先ほどの例に-Esjis:sjis を指定してもやはりASCIIと解釈 > されている(?)みたいです。 > > C:\tmp>type test_sjis.rb > str = "あいうえお" > puts str > > C:\tmp>ruby -v -Esjis:sjis test_sjis.rb > ruby 1.9.1 (2008-12-30 patchlevel-0 revision 21203) [i386-mswin32] > test_sjis.rb:1: invalid multibyte char (US-ASCII) > test_sjis.rb:1: invalid multibyte char (US-ASCII) Ruby 1.9を使い始めた人にははまりやすい点ですが、IOのエンコーディングと スクリプトエンコーディングは「別々」です。 スクリプトエンコーディングはmagic commentで設定します。 個々のスクリプトがエンコーディングを持つことで、別々の文字コードで書かれた スクリプトをシームレスに読み込むことができます。 -Ksな状況においてEUC-JPで書かれたスクリプトを読み込ませようと思ったら、 Ruby 1.8までだと$KCODEを設定しなおさないといけません。 require 'sjis' $KCODE='e' require 'euc' $KCODE='s' 〜 ↓ Ruby 1.9だとエンコーディングが導入されたおかげで require 'sjis' require 'euc' 〜 さて、default_externalについてですが、これは外界(ファイル)の デフォルトのエンコーディングです。これはロケールによって決まってきます。 たとえばWindows環境だとWindows-31J(Shift_JISの亜種/Windowsで使われている) となっているでしょう。 そのため、ファイルを読み込んだときのエンコーディングはWindows-31Jが 前提となります。 しかし、他のエンコーディングのファイルを読み込んでしまうと、 今度はRubyがエンコーディングを誤認してしまいます。 そのときはIOのエンコーディングを明示的に設定してあげる必要があります。 # Rubyが暗黙的にファイルのエンコーディングを推測するわけではありません。 # 以下は、EUC-JPをdefault_externalとします。 普段は通常通り書いてよいです。 $ ruby19 -rkconv -e 'f = File.read("euc.txt"); p [f.encoding, Kconv.guess(f)]' [#, #] EUC-JPの環境でUTF-8のファイルを読み込ませると、Rubyのエンコーディングが 誤認してしまいます。 $ ruby19 -rkconv -e 'f = File.read("utf8.txt"); p [f.encoding, Kconv.guess(f)]' [#, #] そこでdefault_externalをUTF-8に設定しておくと、エンコーディングの不一致が 起こらなくなります。 $ ruby19 -rkconv -E UTF-8 -e 'f = File.read("utf8.txt"); p [f.encoding, Kconv.guess(f)]' [#, #] ただ、default_externalはグローバルな状態なので影響範囲が大きいです。 局所的に別のエンコーディングのファイルを読み込む際には、そのIOのエンコーディングを 設定したほうがよいでしょう。 $ ruby19 -rkconv -e 'f = open("utf8.txt", "r:UTF-8").read; p [f.encoding, Kconv.guess(f)]' [#, #] default_internalはファイル読み込み時に暗黙的にエンコーディングを変換します。 危険なのでおすすめできません。 $ ruby19 -rkconv -E EUC-JP:UTF-8 -e 'f = File.read("euc.txt"); p [f.encoding, Kconv.guess(f)]' [#, #] -- rubikitch Blog: http://d.hatena.ne.jp/rubikitch/ Site: http://www.rubyist.net/~rubikitch/