Hash 如何在puppet中有效地测试深度嵌套的数据值以执行操作?
给定一个数据结构,如Hash 如何在puppet中有效地测试深度嵌套的数据值以执行操作?,hash,puppet,reduce,Hash,Puppet,Reduce,给定一个数据结构,如 $local_users => { "user" => { "ssh" => { "config_entries" => [ { "host" => "dummyhost", "lines" => [ "ProxyCommand /usr/bin/corkscrew proxy.example.net 8080 %h %p" ]
$local_users => {
"user" => {
"ssh" => {
"config_entries" => [
{ "host" => "dummyhost",
"lines" => [
"ProxyCommand /usr/bin/corkscrew proxy.example.net 8080 %h %p"
]
}
]
}
}
}
我已经整理了几个reduce调用,但不确定是否有更有效的方法来确定是否有元素匹配某些条件。我认为,如果找到匹配项,这至少会开始跳过后续项,但执行3个reduce调用来提取嵌套得如此之深的内容似乎有点笨拙,我想知道puppet中是否有更好的模式来提取数据以确定是否需要某些内容
$require_corkscrew = $local_users.reduce(false) |$memo, $user| {
$memo or dig44($user[1], ['ssh', 'config_entries'], []).reduce |$memo, $entry| {
$memo or $entry['lines'].reduce |$memo, $line| {
$memo or $line.match(/ProxyCommand.*corkscrew/)
}
}
}
if $require_corkscrew {
$corkscrew_ensure = 'present'
} else {
$corkscrew_ensure = 'absent'
}
package {'corkscrew':
ensure => $corkscrew_ensure,
}
想知道puppet中是否有更好的模式用于提取数据以确定是否需要某些东西
$require_corkscrew = $local_users.reduce(false) |$memo, $user| {
$memo or dig44($user[1], ['ssh', 'config_entries'], []).reduce |$memo, $entry| {
$memo or $entry['lines'].reduce |$memo, $line| {
$memo or $line.match(/ProxyCommand.*corkscrew/)
}
}
}
if $require_corkscrew {
$corkscrew_ensure = 'present'
} else {
$corkscrew_ensure = 'absent'
}
package {'corkscrew':
ensure => $corkscrew_ensure,
}
在数据结构方面有一些可能的改进:
- 考虑避免这种深嵌套
- 考虑避免散列中的可选键,尤其是在中间层
- 考虑最小化散列数组的使用,因为通常只有通过迭代来处理它们
- 对于具有非受控密钥空间的散列,同上
- 请使用Puppet数据类型来记录和强制执行您选择的数据结构
- 在分析集合以计算布尔属性时,请考虑使用该函数,因为这会使您真正短路
- 不要忽略分析哈希的
和keys()
函数,因为它们至少可以在处理复杂数据结构时减少代码的认知负载values()
- 考虑使用直接操作集合的函数和函数变体,而不是迭代集合和在元素上使用标量函数。例如,
match()
any()
计算和match
函数的数组版本,而不是嵌套的缩减。它依赖于undef
是错误的这一事实,并使用dig()
和then()
来处理可选的哈希键。总的来说,我认为这更清晰,重量更轻,但要实现用于分析复杂数据的简单代码,您只能做这么多
$require_corkscrew = $local_users.values.any |$user| {
$user.dig('ssh', 'config_entries').then |$entries| {
$entries.any |$entry| {
$entry.dig('lines').then |$lines| {
! empty($lines.match(/ProxyCommand.*corkscrew/))
}
}
}
}
可以用另一个围绕标量
match()
的any()
替换数组方式的match()
,但是,尽管它有可能在元素方式的意义上稍早短路,但必须对其进行权衡(可能)通过减少函数调用的数量,以及在函数内部而不是在DSL级别进行迭代来提高效率。我发布了一个关于使用dig
解决此问题的答案,但我现在意识到,这对1没有帮助。n
在config\u条目中有一个n个
散列数
数组和2个match
只能在String
类型上调用,而不能在undef
上调用。这非常方便,当时不知道then
函数,这有很大的不同,当然,我们应该更加了解any
函数,但没有完全单击如何应用它。问题是,即使内置事实也是嵌套的,因此您无法真正避免嵌套.dig
使处理它们变得合理,但在处理复杂结构时,木偶并没有那么好