Chef Ruby hash.merge VS hash[new_key]



我在尝试修改厨师食谱时遇到了一个奇怪的问题。我有一个包含大量哈希的属性。对于这些子锤子中的每一个,我想在其中的"标签"哈希中添加一个新的键/值。在我的食谱中,我为每个大哈希中的每一个创建一个"标签"本地变量,并将标签放大为该局部变量。

我想对标签哈希添加一个修改,但是修改必须在编译时间进行,因为该值取决于存储在输入JSON中的值。我的第一个尝试是这样做:

tags = node['attribute']['tags']
tags['new_key'] = json_value

但是,这导致了一个规格错误,该错误表明我应该使用node.default或等效属性分配函数。所以我尝试了:

tags = node['attribute']['tags']
node.normal['attribute']['tags']['new_key'] = json_value

虽然我没有规格错误,但新的键/值没有粘贴。


在这一点上,我到达了"在墙壁上扔东西"阶段并使用了哈希函数,我以前认为它在功能上与Hash ['new_key']相同,用于单个密钥/值对:

tags = node['attribute']['tags']
tags.merge({ 'new_key' => 'json_value' })

这最终有效,但我不明白为什么。这两种方法之间有什么功能差异,导致一种方法被视为原始厨师属性的修改,而不是另一种?

问题是您不能这样使用node['foo']。访问所有属性级别的合并视图。如果您想设置东西,那将不知道将它们放在哪里。因此,您需要通过告诉将数据放在哪里来引导:

tags = node.normal['attribute']['tags']
tags['new_key'] = json_value

或仅:

node.normal['attribute']['tags']['new_key'] = json_value

谨防将事物设置为normal级别,它在每个运行开始时都不会重置,这可能是您在这里想要的,但这确实意味着即使您删除了进行集合的配方代码,该值也会仍然可以在已经运行它的任何节点上。如果您想实际删除事情,则必须明确进行。

最新更新