RubyのYAML
Ruby(1.8以上)ではYAMLライブラリが標準添付ライブラリです。そのため、YAMLを扱うには「require 'yaml'」とするだけです。
これでYAML.load(YAML形式から読み込み)、YAML.dump(YAML形式への出力)、
さらに様々なオブジェクトで to_yaml メソッドが使えるようになります。
日本語を含むYAMLを出力
しかしこのままでは、日本語文字列を含んだオブジェクトをYAMLドキュメントとして出力すると、日本語部分がバイナリ文字列になってしまいます。
これでは人間にも読みやすいというYAMLの特徴が台なしです。
# -*- coding: utf-8 -*- require 'yaml' puts YAML.dump({'あ' => 'い'}) # 【出力結果】 # --- # "\xE3\x81\x82": "\xE3\x81\x84"
これを解消する方法を軽く検索してみると、
gemで違うYAMLライブラリを入れるとか、パッチをあてるなどの情報が出てきます。
Ruby1.9.2では:Psych
Ruby1.9.2からは、PsychというYAMLパーサも標準添付ライブラリになっています。(以前からあるのは、Syckというライブラリ)
このPsychは「require 'yaml'」するだけでは有効にならないので、以下のようにします。
# -*- coding: utf-8 -*- require 'yaml' YAML::ENGINE.yamler = 'psych' puts YAML.dump({'あ' => 'い'}) # 【出力結果】 # --- # あ: い
今度は日本語がバイナリ文字列化されませんでした。
この方法はTwitter上で @sakuro さんに教えて頂きました。
ありがとうございました!
(2010年10月9日夜に追記↓)
YAML::ENGINE.yamlerを使わなくとも、「yamlの前にpsychがロードされていればOK」とのことです。
つまり以下の方法でも良いということになります。
# -*- coding: utf-8 -*- require 'psych' # 追加 require 'yaml' puts YAML.dump({'あ' => 'い'}) # 【出力結果】 # --- # あ: い
上記の追記はTwitterで @n0kada さんに教えて頂きました。感謝です!
ちょっと実験
require 'psych'だけではどうでしょうか。# -*- coding: utf-8 -*- require 'psych' puts YAML.dump({'あ' => 'い'}) # 【出力結果】 # uninitialized constant Object::YAML (NameError)
エラーになります。YAMLは使えません。
ではrequire 'yaml'が先で、require 'psych'が後だったら?
# -*- coding: utf-8 -*- require 'yaml' require 'psych' puts YAML.dump({'あ' => 'い'}) # 【出力結果】 # --- # "\xE3\x81\x82": "\xE3\x81\x84"
Syckが使われてしまうようです。
1.9.2なのにPsychが使えないよ?
Ruby1.9.2なのにPsychが使えない場合は、 libyaml-dev を入れてからRubyを再コンパイルしましょう(パッケージ名は、Ubuntu 等の場合)。Psychという名前
PsychであってPsyckじゃないんですね。前のライブラリがSyckなのでちょっと紛らわしい。
Ruby1.9.3では(2011年11月28日追記)
コメントで教えて頂いた情報によると、Ruby1.9.3からは、Psychの方がデフォルトになっているようです。
ですので、require 'yaml' 以外に余計な事を書かなくても、日本語を正しく扱うことができます。
逆に Syck を使いたい場合は、YAML::ENGINE.yamler='syck' としなければなりません。
Ruby 1.9.3では、デフォルトでPsychになったようですね。Syckをつかうときは、YAML::ENGINE.yamler=‘syck’と明記する必要があるみたいです。
返信削除Psychはよく知らないのですが、Syckの日本語文字の扱いには手を焼いていたので、期待しています。
>よしのぼりんさん
返信削除情報ありがとうございます!
確かに、require 'yaml' 以外に何もつけなくても、
日本語をきちんと表示してくれました。
記事の方にも追記しておきました!