2010-01-01 25 views
13

Dường như với tôi thư viện YAML đi kèm với ruby ​​1.9 bị điếc.Ruby 1.9, YAML, và mã hóa chuỗi: làm thế nào để sống một cuộc sống của sự tỉnh táo?

Điều này có nghĩa là khi tạo YAML, nó sẽ lấy bất kỳ chuỗi byte nào và thoát khỏi bất kỳ chuỗi byte nào không xuất ra ASCII sạch. Đó là lame, nhưng chấp nhận được.

Vấn đề của tôi là một cách khác. Khi tải nội dung từ YAML dump nói.

Trong ví dụ sau tôi tạo chuỗi UTF-8, đổ nó, nó được bán với loại !binary. Khi tôi tải nó trở lại, nó có mã ASCII-8BIT. Trong phần cuối của ví dụ, tôi cố gắng nối cả chuỗi gốc và chuỗi được tải lại với một chuỗi UTF-8 khác. Sau này sẽ thất bại với một 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 

Tôi nghĩ rõ ràng điều này sẽ nhanh chóng dẫn đến rắc rối khi bạn xử lý một số nguồn YAML có chứa chuỗi lồng và mảng lồng nhau.

Hiện tại tôi có một số mã đi qua tất cả các mảng và mảng và gọi force_encoding trên mỗi chuỗi. Điều đó, để nói rằng ít nhất, là khó coi.

Điều tôi đang tìm kiếm ngay bây giờ là cách để báo cho YAML::load rằng bất kỳ chuỗi nào có trong đó phải được xử lý và do đó mã hóa được đặt thành UTF-8.


Lý tưởng nhất, YAML của Ruby nên chỉ chú thích các chuỗi nó đổ bằng mã hóa thích hợp. Có một dự án Ya2YAML cố gắng để kết xuất YAMF-8 YAML an toàn. Tôi không chắc nó ở xa bao xa. Nếu có ai chơi với nó, tôi hoan nghênh mọi suy nghĩ.

Bất kể điều đó, tôi vẫn có các bãi chứa này mà không cần bất kỳ thông tin mã hóa nào để xử lý. Mặc dù tôi biết họ đều là UTF-8.

+2

+1 cho umlauts kim loại nặng. –

+0

Tôi chỉ chạy vào cùng một lỗi/hành vi ... Bạn đã tìm thấy một giải pháp khác hay bạn vẫn chỉ làm YAML.load và sau đó force_encoding ('utf-8') trên mỗi chuỗi? – severin

Trả lời

1

Trước tiên, tệp văn bản mà bạn đang cố gắng đọc phải được mã hóa UTF-8 (đây là tệp YAML của bạn).

Sau đó, thêm dòng này vào phía trên cùng của tập tin ruby, băm của bạn và tất cả

# encoding: UTF-8 

Điều này sẽ có nghĩa là mã hóa mặc định cho tất cả các chuỗi sẽ UTF-8, và nên có nghĩa là bất kỳ văn bản mà bạn đổ với YAML.dump ('văn bản') hoặc thậm chí chuỗi ký tự 'như thế này' cũng phải được mã hóa UTF-8 và tất cả sẽ hoạt động tốt từ đây.

+0

Không quan trọng. Công cụ đọc dưới dạng nhị phân từ kết thúc yaml dưới dạng ASCII-8BIT, vì các lý do rõ ràng và lành mạnh, nhưng vì vậy yaml nên loại bỏ các chuỗi UTF8 không được thoát đúng cách. Tôi nhiều hơn hoặc ít hơn có một giải pháp cho điều này nhưng liên quan đến một đoạn mã tốt. Tôi sẽ đăng một câu trả lời khi tôi có sẵn đá quý. – kch

3

Hãy cân nhắc nâng cấp ruby ​​của bạn lên phiên bản 1.9.2 mới nhất .

Tôi phát hiện thấy lỗi đó trong 1.9.1 nhưng không phải 1.9.2.

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

Evgeny của câu trả lời vẫn cho thấy nhị phân đối với tôi, nhưng công trình này ('syck' instoad của 'psych'):

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

Tôi đang sử dụng của Ruby 1.9. Lưu ý cho mục đích của tôi có đặc biệt được thoát là tốt - Tôi chỉ cần nó để không hiển thị! Nhị phân ... cho các từ thông thường. Cảm ơn thần .to_yaml là chức năng cho tôi một lần nữa - được sử dụng để sử dụng nó tất cả các thời gian. Cách tải cuộc sống của sự tỉnh táo thực sự :)

+0

Cảm ơn bạn đã sửa chữa user1262147 - yamler = 'psych' không làm gì cho tôi, nhưng yamler = 'syck' đã sửa nó. Trước đây to_yaml đã được bán phá giá tất cả mọi thứ như! Nhị phân = bất cứ điều gì - ngay cả tên thuộc tính từ một ActiveRecord đến từ một bảng mysql UTF8. –

+0

Câu trả lời là lỗi thời, nó đã lỗi thời khi nó được thực hiện, syck là lỗi thời – bbozo

Các vấn đề liên quan