2011-10-27 31 views
6

Tôi đã hỏi một câu hỏi trước về serialization và validation. Có ai đó đã đề cập đến việc sử dụng đá quý JSON, cho phép tôi nói với đối tượng của tôi cách serialize với phương thức to_json, tuy nhiên Ruby dường như làm rất nhiều thứ phức tạp thực sự dễ dàng, tuy nhiên ở một số thứ thực sự đơn giản có vẻ khá phức tạp, một trong những điều đó.Nối tiếp một đối tượng thành JSON, XML, YAML?

Tôi muốn tìm hiểu nếu có một cách để có một đối tượng sạch:

class CleanClass 
    attr_accessor :variable1 
    attr_accessor :variable2 
    attr_accessor :variable3 
end 

cleanObject = CleanClass.new 

Lý tưởng nhất, tôi không muốn bẩn mô hình, tôi chỉ muốn vượt qua nó để một cái gì đó và cho nó biết loại đầu ra nên là gì và để nó hoạt động như thế nào.

Một ví dụ sẽ là một cái gì đó như:

jsonOutput = MagicSerializer::Json.Serialize(cleanObject) 
xmlOutput = MagicSerializer::Xml.Serialize(cleanObject) 
yamlOutput = MagicSerializer::Yaml.Serialize(cleanObject) 

revertedJsonObject = MagicSerializer::Json.Unserialize(jsonOutput) 
revertedXmlObject = MagicSerializer::Xml.Unserialize(xmlOutput) 
revertedYamlObject = MagicSerializer::Yaml.Unserialize(yamlOutput) 

Tôi muốn vượt qua một cái gì đó một đối tượng, và nhận được chuỗi outputted, sau đó có thể chuyển đổi nó trở lại.

Tôi biết ActiveModel có chức năng tuần tự hóa nhưng tôi cần phải làm bẩn lớp học của mình để thực hiện việc này và tôi không muốn thay đổi mô hình nếu có thể. ActiveSupport dường như thỏa mãn các tiêu chuẩn JSON vì tôi chỉ có thể gọi nó và nó sẽ lấy một đối tượng và nhổ ra JSON, nhưng tôi muốn hỗ trợ các kiểu khác.

Mọi thông tin khác sẽ tuyệt vời!

+0

'JSON.dump (đối tượng)' và 'JSON.parse (string) ' – Kris

Trả lời

11

Ruby có tích hợp tự động hóa tuần tự/deserialization thành nhị phân và yaml.

YAML:

require 'yaml' 
serialized = CleanClass.new.to_yaml 
object = YAML.load(serialized) 

Marshal:

serialized = Marshal.dump(CleanClass.new) 
object = Marshal.load(serialized) 
+0

Vâng, tôi đã thấy chúng, nhưng Json là quan trọng nhất hiện nay đối với tôi, sau đó là Xml, sau đó Yaml. Vì vậy, tôi đã hy vọng sẽ có một viên ngọc hoặc thư viện làm mọi thứ từ trên giao diện đơn giản. – Grofit

+1

Định dạng JSON quá hạn chế để nắm bắt trạng thái của toàn bộ đối tượng ruby. Nó chỉ có các nguyên thủy, vì vậy bạn sẽ cần phải tùy chỉnh JSON của bạn để bao gồm thông tin kiểu của các biến cá thể. Hơn nữa, nếu mục tiêu là serialization để đối tượng có thể được đọc lại ở một nơi khác, có thể bạn sẽ cần phải tuân theo một API. Bạn có thể nói trách nhiệm của một lớp là tự chuyển đổi sang định dạng bên ngoài và đọc định dạng đó trở lại. – Ewout

+0

Như tôi đã nói trong phản hồi với Dave ở trên, tôi không hiểu tại sao bạn cần phải nói cho ruby ​​cách sắp xếp các lớp này (sử dụng các giả định) ở trên). Tất cả những gì họ thực sự cần là một phương pháp đệ quy để đi qua từng trường hợp của một đối tượng, cho đến khi chúng tới được một đối tượng khác, sau đó đi sâu hơn vào trong cây, tôi chắc chắn tất cả các đối tượng đều kết thúc như một mô hình kiểu đơn giản ở cuối. Thời gian duy nhất tôi có thể nhìn thấy người dùng cần phải nhập bất kỳ logic serialization tự là nếu họ muốn thay đổi tên của các phím, tức là attr_accessor: Họ được serialized để lastname hoặc một cái gì đó tương tự. – Grofit

1

Đối với JSON và YAML nó có vẻ khá dễ dàng, vì họ sẽ chỉ là wrappers cho to_yamlto_json phương pháp (hoặc YAML.loadfrom_json tương ứng)

Đối với JSON bạn sẽ phải quấn lớp riêng xung quanh lõi-loại (hoặc các loại khác thực hiện to_json) đầu tiên thực hiện một phương thức to_hash mà sau đó có thể được chuyển đổi thành json.

XML phức tạp hơn nhiều vì khía cạnh phân cấp, bạn phải chuẩn hóa nó, nhưng thực sự tôi không hiểu từ lời giải thích của bạn điều gì sai với phương thức cơ bản to_.... Đây thực sự là quy ước chúng tôi sử dụng trong Ruby. Nếu bạn lo ngại về sự ô nhiễm của các mô hình, bạn có thể đặt các phương thức này trong một mô-đun và bao gồm các mô-đun trong lớp.

module Foo 
    def to_serialized_type 
    ... 
    end 
end 
class CleanClass 
    include Foo 
end 
+0

Khi bạn đang cố gắng sử dụng to_xxxx với một thể hiện của một trong các lớp của riêng bạn, bạn phải viết một phương thức to_xxxx trong lớp của bạn để cho nó biết cách tuần tự hóa (từ những gì tôi hiện đang đọc hoặc nó xuất hiện như # <9135f3> thay vì {something: blah}). Đó là vấn đề tôi không muốn có để gây ô nhiễm mô hình với mối quan tâm serialization. – Grofit

+0

Tôi sẽ không gọi nó là gây ô nhiễm, vì đó là cách bạn làm việc bình thường trong ruby: trực tiếp trên đối tượng thay vì chức năng – robustus

1

Có phương pháp serialization kỳ diệu của bạn bẩn đối tượng cho bạn; các emdirtering có thể xảy ra trên một cơ sở cho mỗi đối tượng.

Hoặc bị bẩn ở cấp lớp của bạn.

Dù bằng cách nào, mã chính của bạn cũng không nhìn thấy.

+0

Bạn có thể xây dựng thêm, tôi biết bạn có thể thêm vào các lớp học sau khi khai báo, đó có thể là những gì bạn muốn nói.Tuy nhiên ngay cả khi tôi đã viết một số mã bên ngoài lớp đó để cho nó biết làm thế nào để tuần tự hóa, đó là mã nhiều hơn tôi phải duy trì trong dự án của tôi, và sẽ phải được viết cho mỗi loại lớp. tức là nếu một lớp Person có tên và họ, thì một lớp nghiệp vụ có tên, trường địa chỉ thì bạn sẽ cần phải viết 2 bit riêng biệt của logic tuần tự hóa để xử lý chúng, với đồ thị đối tượng phức tạp sẽ bắt đầu trở nên không thể duy trì. – Grofit

+0

Mã tuần tự hiện tại không được cho biết cách viết ra một đối tượng, ít nhất là đối với các thuộc tính đơn giản, nó thẩm vấn đối tượng. Nếu bạn có nhu cầu serialization phức tạp, bạn sẽ phải nói cho nó như thế nào/một nơi nào đó /. Về cơ bản, bạn yêu cầu hai điều: Tôi muốn kiểm soát hoàn toàn lớp của mình được tuần tự hóa như thế nào, nhưng tôi không muốn thông tin đó trong lớp của mình, và tôi muốn nó được xử lý tự động. Nó không hoạt động như thế - bạn cần xác định cách nó sẽ được tuần tự hóa/ở đâu đó /. –

+0

Hãy để tôi chỉ làm rõ, tôi không yêu cầu hoàn toàn kiểm soát cách lớp của tôi được đăng. Tôi chỉ muốn nó serialized, các giả định sau đây có thể được thực hiện của bất kỳ lớp học được tự động serialized mà không có bất kỳ nỗ lực trên một phần người dùng. Chỉ có các trường/vars có thể truy cập công khai được tuần tự hóa và chúng được sử dụng như một cặp khóa giá trị UNLESS giá trị là một lớp khác, trong đó bạn sử dụng đệ quy để tiếp tục đi xuống cây cho đến khi tất cả các kiểu đơn giản đã được tuần tự hóa. Tôi nghĩ rằng họ là những giả định công bằng và (mặc dù tôi không biết ruby ​​là tốt) nên được dễ dàng, đủ để có được quyền truy cập vào. – Grofit

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