YAML - это сериализованная версия объекта, будь то хеш или массив. Из-за того, как это делает сериализатор, в соответствии со спецификацией мы не можем вставлять строку в вывод любого старого места, она должна быть синтаксически правильной. И самый простой способ сделать это - позволить парсеру YAML и сериализатору обрабатывать его для вас.
Например:
require 'yaml'
foo = {'a' => 1}
puts foo.to_yaml
который выводит:
---
a: 1
и представляет собой простой хэш в формате YAML.
Мы можем сделать туда-обратно, показывая, что это правильно:
bar = foo.to_yaml
YAML.load(bar) # => {"a"=>1}
Более сложный объект показывает, как он может получить сложно:
foo = {'a' => [1,2], 'b' => {'c' => [3, 4]}}
puts foo.to_yaml
что приводит:
---
a:
- 1
- 2
b:
c:
- 3
- 4
Существуют и другие способы назначения массива, но это значение по умолчанию для сериализатора. Если вы добавили строку, в зависимости от того, что вы добавляете, она должна быть до a:
или b:
, что было бы болью при написании кода или добавлении в файл после - 4
.
Вместо этого мы можем загружать и анализировать файл, но, тем не менее, мы хотим переделать результирующий объект, а затем переписать файл YAML, зная, что синтаксис будет прав.
В следующем коде, представьте, что bar
является результатом использования YAML-х load_file
, который считывает и анализирует файл YAML, вместо моего использования load
который только разбирает сериализированную объект:
require 'yaml'
bar = YAML.load("---\na: [1]\n") # => {"a"=>[1]}
я могу изменить bar
:
bar['b'] = {'c' => [2,3,4]}
Вот модифицированный объект:
bar # => {"a"=>[1], "b"=>{"c"=>[2, 3, 4]}}
и сериализации с помощью to_yaml
напишут правильно YAML:
bar.to_yaml # => "---\na:\n- 1\nb:\n c:\n - 2\n - 3\n - 4\n"
Если бы это было:
File.write('foo.yaml', bar.to_yaml)
вы выполнили замену без каких-либо реальных хлопот.
Вместо того чтобы просто перезаписать файл, я рекомендую следовать правилам безопасной перезаписи файлов, записывая новый файл, переименовывая старый, переименовывая новое в имя старого, а затем удаляя переименованный старый файл. Это помогает убедиться, что файл не сбивается, если код или машина умирают, что приводит к потере всех ваших данных.
Не уверен, что я точно понимаю, что вы хотите сделать, но '# to_yaml' возвращает строку, поэтому после факта вы сможете использовать любой метод String. – moveson
Обновлено мое сообщение, чтобы, надеюсь, очистить любую путаницу. Спасибо, что ответили! –
Кажется, что вы читаете файл YAML за один раз, но пытаетесь записать в другой файл YAML по строкам. Написание YAML вручную по строкам очень подвержено ошибкам (и я не вижу веских причин сделать это именно так). Вместо этого создайте свою структуру данных в памяти и напишите файл YAML за один раз. – spickermann