Как эффективно проверить глубоко вложенные значения данных в кукол, чтобы предпринять действие? - PullRequest
1 голос
/ 07 марта 2019

Учитывая структуру данных, такую ​​как

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

Я собрал пару сокращенных вызовов, но не совсем уверен, существует ли более эффективный способ определить, существует ли элемент, соответствующий некоторому условию.Я думаю, что это, по крайней мере, начнёт пропускать последующие элементы, если совпадение найдено, но, кажется, немного неуклюже делает 3 сокращения вызовов, чтобы извлечь что-то глубоко вложенное, и задается вопросом, есть ли в марионетке какие-то лучшие шаблоны для извлечения данных, чтобы определить, что-тотребуется или нет.

$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 Ответ

2 голосов
/ 08 марта 2019

задается вопросом, есть ли в марионетке более эффективные шаблоны для извлечения данных, чтобы определить, требуется ли что-то или нет.

Есть несколько возможных улучшений в том, как вы структурируете свои данные:

  • рассмотрите возможность избежать такого глубокого вложения
  • не используйте дополнительные ключи в ваших хешах, особенно в средних слоях
  • рассмотрите возможность минимизации использования массивов хэшей, поскольку, как правило, нет способа обрабатывать их, кроме как перебирать их.
  • То же самое для использования хэшей с неконтролируемыми ключевыми пространствами
  • действительно используйте типы данных 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.

...