【问题标题】:Chef Ruby hash.merge VS hash[new_key]主厨 Ruby hash.merge VS hash[new_key]
【发布时间】:2018-02-22 05:00:43
【问题描述】:

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

我想对标签哈希添加修改,但修改必须在编译时完成,因为该值取决于存储在输入 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,但请记住 [] 是一种可以被覆盖的方法,因此可能 Chef 使用的并不是真正的 Hash,而是使用类似接口的东西。
  • 听起来很可能。我假设我最初的理解适用于标准 Ruby 是否正确?
  • node 不是HashnodeChef::Node [] 方法使您可以访问 Chef::Attribute 也不是 Hash 但更接近它是 Mash 这是 Chefs 的子类 Hash。为什么第一个版本不起作用我无法解释,因为[]=(arg) 是作家。此外,为什么merge 确实有效也没有任何意义,因为它不是破坏性的(意味着它创建一个副本并修改副本,使原件保持不变)本质上[]= 实际上类似于merge!

标签: ruby hash chef-infra


【解决方案1】:

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

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

或者只是:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    • 2010-12-28
    • 1970-01-01
    • 2013-12-08
    • 2018-10-19
    • 2018-09-29
    • 2012-03-22
    相关资源
    最近更新 更多