厨师Ruby hash.merge VS hash [new_key]

时间:2018-02-21 16:20:08

标签: ruby hash chef

在尝试修改厨师食谱时遇到了一个奇怪的问题。我有一个包含哈希大散列的属性。对于每个子哈希,我想为一个'标签添加一个新的键/值。哈希内。在我的食谱中,我创建了一个标签'每个大哈希的局部变量,并将标签哈希值分配给该局部变量。

我想添加对标签哈希的修改,但修改必须在编译时完成,因为该值取决于存储在输入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.merge函数,我曾经认为函数与hash [' new_key']在功能上相同,只增加了一个键/值对:

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

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

1 个答案:

答案 0 :(得分:0)

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

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

或者只是:

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

请注意设置normal级别的东西,它不会在每次运行开始时重置,这可能是你想要的,但它确实意味着即使你删除配方代码执行集合,该值仍将存在于已运行它的任何节点上。如果你想真正删除东西,你必须明确地做。