From: "Y. Nobuoka" Date: 2011-09-27T10:15:45+09:00 Subject: [ruby-list:48418] Re: Ruby 1.9 で Shift JIS の YAML 5.5 さん 信岡です。 > ところが,Ruby 1.9 では,Shift JIS の YAML テキストを与えても, > UTF-8 としてパースしているように見えます。 > Shift JIS として解釈させる方法がありますか? Ruby 1.9 では、UTF-8 としてパースしているというよりも、 Ruby 1.8 と同じく文字エンコーディングを気にせずにパースして、 結果の文字列のエンコーディングを問答無用で UTF-8 に指定しているように思います。 (YAML ライブラリの中身をちゃんと見ていないので間違えているかもしれません。) そのため、 force_encoding メソッドを使って YAML ライブラリの出力文字列のエンコーディングを 本来のエンコーディングに戻してやるという方法で使えないことはないと思います。 #! ruby1.9 -ECP932:CP932 # coding: CP932 require "yaml" text = '- 日本語' # YAML.load の結果が問答無用で UTF-8 になるのでエンコーディングを指定しなおす str = YAML.load( text ).first.force_encoding( Encoding::CP932 ) puts text.encoding, #=> Windows-31J str.encoding, #=> Windows-31J str.size, #=> 3 str.unpack( 'C*' ).map{ |c| c.to_s( 16 ).upcase }.join( ' ' ) #=> 93 FA 96 7B 8C EA しかしながら、Shift_JIS (または CP932) では、特定の文字の 2 バイト目が バックスラッシュのバイト値と同じになりますので、例えば以下のような場合に エラーが発生してしまいます。 (これは Ruby 1.8 でも 1.9 でも同様です。) #! ruby1.8 -Ks require "yaml" text = '[ "噂" ]' # CP932 の '噂' の 2 バイト目はバックスラッシュと同じバイト値 str = YAML.load(text).first # エラー発生 puts text.encoding, str.encoding, str.size puts str.unpack( 'C*' ).map{ |c| c.to_s( 16 ).upcase }.join( ' ' ) どうしても Shift_JIS を使わなければいけない、というのでないならば、 UTF-8 に変換してから YAML.load に投げる、というのが安全だと思われます。 -- 信岡 ゆう (NOBUOKA Yu)