我生成了我的厨师属性服务配置。 然而,在某些时候,我需要把属性捣烂成一个简单的红宝石哈希值。 这用在厨师10以做工精细:
node.myapp.config.to_hash
但是,从厨师11,这是行不通的。 只有属性的顶层被转换为哈希值,与剩余的不可变的压薄的物体然后嵌套值。 修改它们会导致这样的错误:
厨师::例外:: ImmutableAttributeModification ------------------------------------------- -----节点的属性是只读的,当你不指定优先级设置。 要设置一个属性代码使用像`node.default [“键”] =“值””
我已经尝试了一堆的方式来解决这个问题,它不工作:
node.myapp.config.dup.to_hash
JSON.parse(node.myapp.config.to_json)
该JSON解析黑客攻击,这似乎像它应该工作的伟大,其结果是:
JSON::ParserError
unexpected token at '"#<Chef::Node::Attribute:0x000000020eee88>"'
是否有任何实际可靠的方式,总之包括每个食谱嵌套解析功能,属性转换为简单,普通,好老的红宝石哈希?
后都在这里和Opscode公司厨师邮件列表上一个响亮的缺乏答案,我结束了使用下面的技巧:
class Chef
class Node
class ImmutableMash
def to_hash
h = {}
self.each do |k,v|
if v.respond_to?('to_hash')
h[k] = v.to_hash
else
h[k] = v
end
end
return h
end
end
end
end
我投入我的菜谱目录库这一点; 现在我可以在这两个厨师10使用attribute.to_hash(已经工作正常并且通过这种猴子补丁不受影响)和厨师11.我也报这个作为Opscode公司的错误:
如果你不希望有猴子补丁的厨师,说出来对这个问题: http://tickets.opscode.com/browse/CHEF-3857
我希望我不是太晚了党合并,但使用空哈希节点对象为我做:
chef (12.6.0)> {}.merge(node).class
=> Hash
我有同样的问题,经过大量黑客周围想出了这一点:
json_string = node[:attr_tree].inspect.gsub(/\=\>/,':')
my_hash = JSON.parse(json_string, {:symbolize_names => true})
检查确实是从提出的其他方法缺失的深层解析和我结束了,我可以修改,并根据需要通过周围的哈希值。
以上答案是有点不必要。 你可以这样做:
json = node[:whatever][:whatever].to_hash.to_json
JSON.parse(json)