我正在使用Thor并尝试将YAML输出到一个文件.在irb我得到我的期望YAML格式的纯文本.但是当Thor的一部分方法,其输出是不同的…
class Foo < Thor include Thor::Actions desc "bar","test" def set test = {"name" => "Xavier","age" => 30} puts test # {"name"=>"Xavier","age"=>30} puts test.to_yaml # !binary "bmFtZQ==": !binary |- # WGF2aWVy # !binary "YWdl": 30 File.open("data/config.yml","w") {|f| f.write(test.to_yaml) } end end
有任何想法吗?
解决方法
所有Ruby 1.9字符串都附有一个编码.
YAML将一些非UTF8字符串编码为二进制,即使它们看起来无辜,也没有任何高位字符.您可能会认为您的代码始终使用UTF8,但内置函数可以返回非UTF8字符串(ex文件路径例程).
为了避免二进制编码,请确保在调用to_yaml之前,所有的字符串编码都是UTF-8.使用force_encoding(“UTF-8”)方法更改编码.
例如,这是我如何将我的选项哈希编码为yaml:
options = { :port => 26000,:rackup => File.expand_path(File.join(File.dirname(__FILE__),"../sveg.rb")) } utf8_options = {} options.each_pair { |k,v| utf8_options[k] = ((v.is_a? String) ? v.force_encoding("UTF-8") : v)} puts utf8_options.to_yaml
这是一个将二进制的简单字符串编码为yaml的例子
>> x = "test" => "test" >> x.encoding => #<Encoding:UTF-8> >> x.to_yaml => "--- test\n...\n" >> x.force_encoding "ASCII-8BIT" => "test" >> x.to_yaml => "--- !binary |-\n dGVzdA==\n"