Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 检查Chef中是否存在嵌套属性的正确方法是什么?_Ruby_Chef Infra_Chef Recipe - Fatal编程技术网

Ruby 检查Chef中是否存在嵌套属性的正确方法是什么?

Ruby 检查Chef中是否存在嵌套属性的正确方法是什么?,ruby,chef-infra,chef-recipe,Ruby,Chef Infra,Chef Recipe,有多种方法可以检查chef中是否存在嵌套属性,我不确定哪种方法是正确的/最好的,如果有,将导致节点上存储空属性: 节点[:父节点]和节点[:父节点][:子节点] node.attribute?(:parent)和node[:parent]。attribute?(:child)) 节点[:父节点].nil?和节点[:父节点][:子节点].nil? 最好能同时检查父母和孩子,但我不知道这是否可行。我使用的是Chef 10,而不是Chef 11,不过欢迎回答解释这两种方法。节点属性对象是HashMa

有多种方法可以检查chef中是否存在嵌套属性,我不确定哪种方法是正确的/最好的,如果有,将导致节点上存储空属性:

节点[:父节点]和节点[:父节点][:子节点]
node.attribute?(:parent)和node[:parent]。attribute?(:child))
节点[:父节点].nil?和节点[:父节点][:子节点].nil?

最好能同时检查父母和孩子,但我不知道这是否可行。我使用的是Chef 10,而不是Chef 11,不过欢迎回答解释这两种方法。

节点属性对象是HashMap。您可以使用ruby原生API查找嵌套属性

Chef节点对象提供了许多辅助方法,如:

node.attribute?()
node[:foo].attribute?(:bar)
node[:foo].member?(:bar)
chef 11中还有一个新方法
node.debug_value()
,可以帮助您调试节点属性,这也很有帮助:

node.debug_value(:foo, :bar)

详细信息可以从文章中找到。

查看chef sugar cookbook extension,它允许安全地引用深层属性。

我最近解决这个问题的方法是尽可能始终为烹饪书中使用的属性设置默认值

例如,
cookbook/attributes/default.rb
将包含:

default[:parent][:child] = nil
在配方中,对属性值的任何检查都可以减少为:

node[:parent][:child].nil?

当然,有一个可用的默认值并且根本不需要检查通常更有用。

我发现了一个非常优雅的解决方案,它在
if
条件的末尾使用了
rescue NoMethodError

if node['foo']['bar']['baz']
   do the stuff I want
end rescue NoMethodError
正确的“现代”方法是使用
exist?()
helper:

if node.exist?('foo', 'bar', 'baz')
  # do stuff with node['foo']['bar']['baz']
end
这取代了旧的chef sugar
deep_fetch
机制,并在chef client中内置了很长一段时间

还有一个
read()
helper来获取值,如果中间键不存在,它将返回nil:

fizz = node.read('foo', 'bar', 'baz')
它与后来添加到ruby中的Hash#dig方法相同,ruby也支持作为别名:

fizz = node.dig('foo', 'bar', 'baz')

这也将挽救由添加到条件中的任何其他子句引起的任何nomethoderor(因此在扩展到
的if节点['foo']['bar']['baz']&&shoulddoit?
下,将吞噬
def shoulddoit?
中引起nomethoderor的任何编程错误)。它还将拯救“做我想做的事”块所引发的任何命名错误。对于绝对琐碎的情况,这是可行的,但一旦琐碎的情况变得复杂,这将极大地阻碍调试任何东西的能力。不应使用此解决方案。在链接的网页中,如果作者键入了
包括_recipie“ganglia::default”
(配方中的额外i,这是一种相当常见的拼写错误),则rescue会接受有关键入的错误。