Выходные данные Yaml заполнены! Map: ActiveSupport :: HashWithIndifferentAccess - PullRequest
4 голосов
/ 05 июля 2011

Я обновился до rails 3.0.9 и появился новый драгоценный камень yaml.К сожалению, способ вывода to_yaml довольно большого хэша как-то изменился.Теперь я получаю много «! Map: ActiveSupport :: HashWithIndifferentAccess» после элементов, которые я не получал раньше, что, насколько я понимаю, является ошибкой, потому что я пытаюсь сделать мой .yml максимально читабельным для человека,Есть ли способ избавиться от "! Map: ActiveSupport :: HashWithIndifferentAccess" из вывода yaml?Это не влияет на то, как оно загружается в мой код, поэтому я не вижу смысла в том, что он есть в выводе.Я мог бы просто gsub это, но я думаю, что здесь происходит что-то еще, что я не знаю.

Типичный ввод хэша:

{"All" => 
  {"A test" => {"string"=>"This is just a test",
               "description" => "This is a description for a test string",
               "alternatives" => [{"new" => "woot"}]}}

Вывод Yaml:

All:
  A test: !map:ActiveSupport::HashWithIndifferentAccess 
    string: This is just a test
    description: This is a description for a test string
    alternatives:
    - !map:ActiveSupport::HashWithIndifferentAccess 
      new: woot

Что я хочу (и что я получал раньше):

All:
  A test:
    string: This is just a test
    description: This is a description for a test string
    alternatives:
      - new: woot

Примечание: мой вывод должен быть в UTF-8.

Ответы [ 2 ]

4 голосов
/ 05 июля 2011

Я подозреваю, что ваш хэш получен от params в контроллере, который имеет тип ActiveSupport::HashWithIndifferentAccess. Один из способов исправить вывод - обезьяна исправляет метод to_yaml, чтобы преобразовать себя в обычный хэш перед преобразованием его в YAML.

# config/initializers/hash_with_indifferent_access.rb
class HashWithIndifferentAccess < Hash
  def to_yaml(opts = {})
    self.to_hash.to_yaml(opts)
  end
end
2 голосов
/ 30 декабря 2011

Я в той же проблеме, я думал в решении @ htanata , также возможно реализовать это monkey patch :

class HashWithIndifferentAccess < Hash
  def to_yaml_typea
    ""
  end
end

Но это также очень опасно.

Я думал о реализации моего собственного YAML :: Emitter , но это выглядело как перерасход технологии.

Это также сработало:

JSON.parse(my_hash_with_indifferent_access.to_json).to_yaml

Но не выглядел слишком эффектно:)

Также приходило мне в голову:

my_hash_with_indifferent_access.to_yaml.gsub( " !map:ActiveSupport::HashWithIndifferentAccess", "" )

Все еще думать возможно, но все мы согласны с тем, что это плохо пахнет.

Мое окончательное решение было :

# config/intializers/hash_with_indifferent_access_extension.rb
# use it like `params.to_hash_recursive.to_yaml`
class HashWithIndifferentAccess < Hash
  def to_hash_recursive
    result = self.to_hash

    result.each do |key, value|
      if(value.is_a? HashWithIndifferentAccess)
        result[key] = value.to_hash_recursive
      end
    end

    result
  end
end

Это также обезьяна-патч , но по крайней мере это обезьяна-патч несуществующего метода , поэтому возможности вмешательства в поведение кода сторонней организации очень странные.

PD : любые предложения по очистке этого кода см. В gist

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