Расширение хэша и (де) сериализация из / в yaml - PullRequest
1 голос
/ 11 сентября 2011

Я нашел этот пример: http://www.yaml.org/YAML_for_ruby.html#extending_kernel::hash

Приятно видеть, как легко YAML может сериализовать хэш. Однако я хотел бы сериализовать свой собственный класс, расширенный хеш с атрибутом в нем.

Как будет выглядеть строка yaml и как лучше всего ее сериализовать?

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 11 сентября 2011

Вы можете взять источник оригинала Hash#to_yaml и переопределить его, добавив все, что вам нужно:

def to_yaml( opts = {} )
  YAML::quick_emit( self, opts ) do |out|
    out.map( taguri, to_yaml_style ) do |map|
      # here you can add something like:
      map.add('my_attribute', @my_attribute)
      # and proceed with the usual Hash serialization:
      each do |k, v|
        map.add( k, v )
      end
    end
  end
end
1 голос
/ 11 сентября 2011

Как показывает ответ Младена Яблановича, вы можете переопределить to_yaml.Вы можете добавить массив с именем «атрибуты» (особенно стараясь избежать этого имени, если в хэше есть ключ с этим именем (стараясь избежать экранированного имени, если ... и т. Д.)).Тем не менее, вам нужно некоторое знание внутренних элементов, чтобы сделать эту работу (out.map(tag_uri, to_yaml_style) и его вариации нетривиальны и плохо документированы: источники различных интерпретаторов Ruby - ваш лучший выбор).

К сожалению, выТакже необходимо переопределить процесс десериализации.То, как вы можете повторно использовать существующий код, близко к полностью недокументированному.Как и в этом ответе , вы должны добавить to_yaml_type и код десериализации, используя YAML::add_domain_type.Оттуда вы в значительной степени сами по себе: вам нужно написать половину парсера YAML, чтобы проанализировать строку yamled и преобразовать ее в ваш объект.

Это можно понять, но более простое решение, которое я реализовал в прошлый раз, когда хотел этого, состояло в том, чтобы просто сделать Hash атрибутом моего объекта вместо расширения Hash.А потом я понял, что на самом деле я не реализую подкласс Hash.То, что что-то хранит пары ключ-значение, не обязательно означает, что является хэшем.Если вы реализуете :[], :[]= и each, вы обычно проделываете долгий путь к возможности обрабатывать объект, как если бы он был хешем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...