如何有效地测试人偶中深层嵌套的数据值以采取措施?

时间:2019-03-07 18:27:08

标签: hash puppet reduce

给出像这样的数据结构

$local_users => {
  "user" => {
    "ssh" => {
      "config_entries" => [
        { "host" => "dummyhost",
          "lines" => [
            "ProxyCommand /usr/bin/corkscrew proxy.example.net 8080 %h %p"
          ]
        }
      ]
    }
  }
}

我已经整理了两个reduce调用,但是并不确定是否有更有效的方法来确定是否存在符合某些条件的元素。我认为这至少会在找到匹配项后开始跳过后续项目,但似乎有点笨拙,因为3减少了对嵌套此嵌套内容的调用,减少了调用,并想知道p中是否有更好的模式来提取数据以确定是否有内容是必需的。

$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,
}

1 个答案:

答案 0 :(得分:2)

  

想知道木偶中是否有更好的模式来提取数据以确定是否需要某些东西。

在数据结构方面有一些可能的改进:

  • 考虑避免此类深层嵌套
  • 考虑避免在散列中使用可选键,尤其是在中间层中
  • 考虑尽量减少使用哈希数组,因为除了迭代之外,通常没有其他方法可以处理这些哈希。
  • 同上,用于具有不受控制的密钥空间的哈希
  • 使用Puppet数据类型来记录和执行您选择的数据结构

关于计算模式,

  • 在分析集合以计算布尔属性时考虑使用any()函数,因为这会使您善意短路。

  • 不要忽略用于分析哈希的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级别进行迭代所带来的(可能)效率提高。