2010-01-01 28 views
13

在我看來,紅寶石1.9附帶的YAML庫是encoding-deaf。Ruby 1.9,YAML和字符串編碼:如何過一種理智的生活?

這意味着當生成YAML時,它將接收任何字節的字符串,並轉義任何不輸出乾淨的ASCII的字節序列。這是跛腳的,但可以接受。

我的問題是相反的。從所述YAML轉儲加載內容時。

在下面的示例中,我創建一個UTF-8字符串,將其轉儲,並將其轉儲類型爲!binary。當我加載它時,它具有編碼ASCII-8BIT。在這個例子的最後,我嘗試用另一個UTF-8字符串連接原始和重新加載的字符串。後者將以Encoding::CompatibilityError失敗。

require 'yaml' 
s0 = "Iñtërnâtiônàlizætiøn" 
y = s0.to_yaml 
s1 = YAML::load y 
puts s0     # => Iñtërnâtiônàlizætiøn 
puts s0.encoding  # => UTF-8 
puts s1     # => Iñtërnâtiônàlizætiøn 
puts s1.encoding  # => ASCII-8BIT 
puts y     # => --- !binary | 
         # ScOxdMOrcm7DonRpw7Ruw6BsaXrDpnRpw7hu 
puts "ñårƒ" + s0  # => ñårƒIñtërnâtiônàlizætiøn 
puts "ñårƒ" + s1  # => Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT 

我想很明顯這將如何迅速引來麻煩,當你處理包含嵌套哈希和數組與葉弦一些YAML源。

目前我有一些遍歷所有哈希和數組的代碼,並在每個字符串上調用force_encoding。這至少可以說是不美觀的。

什麼我要找的,現在是一種方式告訴YAML::load是自帶的任何字符串應被視爲,因此有它的編碼設置爲UTF-8。


理想情況下,ruby的YAML應該只註釋它轉儲的字符串以正確的編碼。有一個Ya2YAML項目試圖轉儲UTF-8安全的YAML。我不確定它有多遠。如果有人玩過它,我歡迎任何想法。

無論如何,我仍然有這些轉儲沒有任何編碼信息來處理。雖然我知道他們都是UTF-8。

+2

+1爲重金屬元素變音。 – 2011-04-18 11:42:54

+0

我只是遇到相同的錯誤/行爲...你有沒有找到另一個解決方案,或者你還只是在做每個字符串的YAML.load然後force_encoding('utf-8')? – severin 2012-07-13 12:24:25

回答

1

首先,您嘗試讀取的文本文件必須使用UTF-8編碼(這應該是您的YAML文件)。

,這一行添加到您的ruby文件,哈希的頂部和所有

# encoding: UTF-8 

這將意味着所有字符串的默認編碼將是UTF-8,而應該意味着任何文本轉儲與YAML.dump('文本'),甚至字符串文字'這樣'也應該被編碼爲UTF-8,並且所有應該從這裏開始工作。

+0

沒關係。從yaml讀取的二進制文件最終爲ascii-8BIT,這可能是明顯和理智的原因,但yaml應該正確轉儲非UTF8字符串。我或多或少有一個解決方案,但涉及一個很好的塊代碼。當我準備好寶石時,我會發佈一個答案。 – kch 2010-07-30 11:59:35

3

考慮升級您的紅寶石到最新的1.9.2 。

我在1.9.1中發現了這個bug,但不是1.9.2。

2
YAML::ENGINE.yamler='psych' 
'Résumé'.to_yaml # => "--- Résumé\n...\n" 
0

葉夫根的答案仍然顯示二進制的我,但這個工程(的 '迷幻' SYCK'instoad):

YAML::ENGINE.yamler='syck' 
'Résumé'.to_yaml # => "--- "R\xE9sum\xE9" 

我使用Ruby 1.9。注意我的目的是讓特殊的東西轉義是好的 - 我只是需要它不顯示!二進制文件...用於正常的單詞。感謝上帝.to_yaml對我來說又是功能性的 - 以前一直用它。如何加載理智的生活確實:)

+0

謝謝你的修正user1262147 - yamler ='psych'對我沒有任何幫助,但是yamler ='syck'修復了它。以前to_yaml已經將所有東西都轉儲爲!binary = whatever - 甚至是來自一個來自UTF8 mysql表的ActiveRecord的屬性名稱。 – 2013-08-11 19:14:27

+0

答案已經過時,它已經過時了,syck已經過時了 – bbozo 2014-03-05 10:00:43

相關問題