В течение многих лет вы смогли продлить кукольный язык, написав пользовательские функции в Ruby. И поскольку функции были автозагрузки из модулей, большая экосистема разработала добавление всех видов функциональности. Например, PuppetLabs/Stdlib
Включает в себя Smorgasbord из строковых манипуляций, проверки данных, структуры данных Muning и т. Д. Но оригинальная функция API имела много критических ограничений, а марионетки ввели новую и улучшенную API с помощью Puppet 4.x. Я хотел бы рассказать вам о некоторых преимуществах и как обновить свои собственные функции на новую API. Это удивительно легко сделать!
Конечный пользователь не заметит много раз разности, за исключением патологических случаев, но дополнительные преимущества будут совокупными. Каждая современная функция Puppet 4.x — чуть быстрее и просто немного безопаснее использовать. Как разработчики модуля портируют свои функции, время компиляции получит все больше и больше исполнения. Современные функции Puppet 4.x имеют улучшенные потоковые данные, управление памятью и время загрузки. Еще более важно, они Изолированный к окружающей среде, которую они загружены из Отказ
Давайте сделаем быстрое резюме этого, потому что это важно и стоит распаковывать последствия. Legacy Mountepet функций подвергались утечке окружающей среды, что вкратце означает, что Наследие функции в среде Dev часто случайно также оценивались в производственных средах Отказ RUBY Runtime разрешит только одну версию функции, поэтому в зависимости от того, что сначала одна нагрузка будет использоваться для всех сред. Эффективно, какой агент не произошел, чтобы проверить первым, будет «блокировать» версию функции, которая будет использоваться для жизни компилятора. Функции Puppet 4.x выделяют в собственной среде, чтобы даже если у вас есть разные версии функции в разных средах, правильный будет использоваться каждый раз, когда скомпилируется каталог.
Разработчик, пишущий кукольный код заметит несколько улучшений, используя новый API. Наиболее очевидным преимуществом, вероятно, является тем, что имена функций имен позволяют намного легче найти определение функции, которую вы используете, и предотвратить коллизии имен. Например, скажем, что модуль в вашей кодовой базе использует наследие API для определения функции с именем Meens_arguments ()
Отказ Это плохая практика, потому что имя не очень уникально, но, к сожалению, не неслыханным. Проблема возникает при установке второго модуля, который также определяет другую функцию с именем Meens_arguments ()
Отказ Это функционально неопределенно, какая функция будет вызываться при использовании этого имени, если существуют две функции с тем же именем. Это означает, что оба модуля, и весь ваш код все будет использовать ту же функцию, а У вас нет способа узнать, какой из них называется!
Современная функция API обеспечивает пространство имен, поэтому, когда вы вызываете MyMod:: Meeng_arguments ()
, вы никогда не запускали MyOthermod:: Means_arguments ()
функция. Вы также можете точно видеть, как найти источник функции на диске, потому что имя показывает, что он находится в MyMod
модуль.
Функции записи разработчиков в Ruby Code увидят наибольшую пользу. Функции, использующие современную API, могут использовать проверку типа в своих подписеях, что означает, что автор больше не нужно писать коду кода, чтобы гарантировать, что правильный вид данных был передан функции. Они также могут писать несколько реализаций функции для решения различных типов аргументов. Например, если вы написали камера ()
Функция, вы можете написать одну реализацию, которую верблюд обоснул строку, а другая реализация, которая приведет к массиву строк и верблюда в каждом элементе, вызывая первую реализацию неоднократно. И поскольку вы не писали реализацию, которые принятые номера, Beavet автоматически бросит ошибку, если пользователь попытался верблюдом чехол в верблюченное значение!
Это уменьшает потребность в функциональной растяне или писать много разных функций, которые делают очень похожие вещи. Вместо этого автор функции может группировать все те в одну функцию, которая включает в себя несколько реализаций и и любой необходимый код помощника. Это также снижает необходимость написания общего библиотечного кода. Теперь, когда у вас было мыслительное управление изобретению ваших собственных камера ()
Функция, вы можете прочитать через Источник встроенной версии Чтобы увидеть пример этого и насколько близко ваши идеи совпадают с его реализацией.
Портирование к современному API
К настоящему времени я надеюсь, что я убедил вас, что стоит обновить ваши модули. Так как вы начинаете? К счастью, это на самом деле довольно легко сделать.
Давайте начнем с поиска подписи и синтаксиса наследие функции Ruby:
#/lib/puppet/parser/functions/strlen.rb module Puppet::Parser::Functions newfunction(:strlen, :type => :rvalue, :doc => "Just a naive strlen example" ) do |args| raise "Wrong number of args" unless args.size == 1 raise "Wrong type of args" unless args.first.is_a String value = args.first value.length end end
Это определение функции требовало вас указать Arcane : введите
Параметр Определение того, возвращает или нет функции значения. Он также просто наполнил все аргументы в массив и требовал от того, как автор вручную обрабатывать указанный массив и обрабатывать любые ошибки проверки или аргумента. Это может быть несколько знакомым для старой школы Perl хакеров, но это ненужная котельная в эти дни.
Вместо этого современная версия этой же функции будет выглядеть так:
#/lib/puppet/functions/mymod/strlen.rb # @summary # Just a naive strlen example # Puppet::Functions.create_function(:'mymod::strlen') do # @param value # The string to calculate the length of # # @return [Integer] # The length of the input string # dispatch :default_impl do # call the method named 'default_impl' when this is matched param 'String', :value end def default_impl(value) value.length end end
Обратите внимание, что, пока он выглядит как можно больше, большинство из него гораздо более выразительные комментарии. Это используют Кукольные струны Формат, SuperSet стандартных Дворовые строки документации Отказ Тело функции — это просто отправка
Вызов метода, который регистрирует функцию Подпись и метод позвонить, когда эта подпись соответствует.
В этом примере есть только одна отправка. Когда функция вызывается с одной строкой в качестве аргумента, default_impl
Метод называется с этой строкой в качестве аргумента. Если функция вызывается любым другим способом, система проверки типа Cupetept запускает ее и поднимает соответствующую ошибку. Стоит отметить, что имя этого метода является произвольным, поэтому выберите все, что имеет смысл для вашей собственной функции.
Если бы были различные типы входных типов данных, которые мы хотели рассчитывать, то мы могли бы написать как можно больше реализации, поскольку мы хотели, и зарегистрировавшими их в типы данных с большим количеством отправка
звонки. Прошло это необходимость выполнять ручную проверку типов, или количество аргументов или любой другой валидации. Прошло это необходимость обрабатывать аргументы Array. Все, что осталось сделать, это реализовать функциональность, которые мы желаем.
Процесс портирования довольно прост. Сначала вы захотите определить различные части устаревшего функции. Есть четыре грубых частях, которые мы рассмотрим отдельно:
- Определение функции и структура. Это не включает подпись функции, потому что это неявно, и нам придется выводить, как обрабатываются аргументы.
- Документация о функции и как она работает.
- Обработка и проверка аргументов. Мы будем использовать это, чтобы вывести подпись (ы).
- Сама реализация.
Давайте снова посмотрим на функцию наследие, аннотированные с частями, которые мы заботимся о.
#/lib/puppet/parser/functions/strlen.rb module Puppet::Parser::Functions newfunction(:strlen, # definition/name :type => :rvalue, :doc => "Just a naive strlen example" # documentation ) do |args| raise "Wrong number of args" unless args.size == 1 # arg validation raise "Wrong type of args" unless args.first.is_a String # arg validation value = args.first # arg handling value.length # implementation end end
Все остальное — это просто ботистота. Теперь нам нужно сделать вывод функциональной подписи (ы). Логика в проверке и обработке аргумента и обработки говорит нам, что мы обрабатываем только один случай: функция будет принимать только один строковый аргумент. Давайте напишем это как отправку.
dispatch :default_impl do param 'String', :value end
: default_impl
Имя — произвольная этикетка. Он говорит кукольной марионелке, который позвонит, когда функция вызывается с подписью, которая соответствует этой структуре. В этом случае он позвонит default_impl ()
Метод, но мы могли назвать его все, что мы хотели, если они оба матча.
Затем в отправке мы используем один или несколько Param
Вызывы для описания подписи функции. Здесь мы звоним только один раз, поэтому эта отправка будет соответствовать только одному Строка
аргумент Обратите внимание, что мы Цитировать название типа Так что это не оценивается как тип синхера. Мы также предоставляем имя для каждого параметра, который будет использоваться в сгенерированной документации и выводе помощи.
API обрабатывает всю другую проверку для нас, поэтому мы закончили вывести подпись и может перейти к реализации. Мы назвали это default_impl ()
Уже, так что давайте напишем этот метод:
def default_impl(value) value.length end
Теперь давайте поставим детали вместе и построить новую функцию. Вообще говоря, наша функция будет в модуле, поэтому мы также имеем пространство пространства новой функции, чтобы включить имя модуля. Обязательно отражайте это на пути.
#/lib/puppet/functions/mymod/strlen.rb Puppet::Functions.create_function(:'mymod::strlen') do # definition/name dispatch :default_impl do param 'String', :value # signature & arg validation end def default_impl(value) value.length # implementation end end
Это минимально жизнеспособный порт. Последний шаг состоит в том, чтобы расширить документацию, используя формат дворных/марионеток, чтобы лучше объяснить, как использовать функцию.
Это только касается простейшего случая. Документы разработчика для создания пользовательских функций Опишите более сложные паттерны отправки, включая переменные повторяющиеся параметры, необязательные параметры и многое другое. Он показывает, как обрабатывать лямбдас, как вызывать другие функции и как писать расширенные итеративные функции. И главное, он описывает некоторые общие готы при рефакторировании устаревших функций, которые мы здесь блестели.
Удачи и счастливого рефакторинга!
- Узнайте больше о Пользовательские функции Отказ
- Узнайте больше о Документировав ваши функции или другой кукольный код Отказ
- Читайте о Ограничения кукольных сред Отказ
- Узнайте о написании Простые функции в кукольном языке вместо рубина.
Оригинал: «https://dev.to/binford2k/upgrade-to-puppet-4-x-functions-already-332j»