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'返回一個字符串,所以你應該可以在事實之後使用任何字符串方法。 – moveson
更新了我的帖子,希望能夠清除任何混淆。感謝您的迴應! –
看起來你正在讀取YAML文件,但嘗試逐行寫入另一個YAML文件。手動逐行寫入YAML非常容易出錯(我沒有看到這樣做的合理理由)。相反,在內存中構建數據結構並一次性寫入YAML文件。 – spickermann