Я не понимаю поведение этого кода Ruby, который я написал внутри шаблона Puppet (erb). Это должно быть связано с каким-то свойством переменных экземпляра, которое я игнорирую и не смог выяснить.
На стороне Puppet переменная $local_users может быть объявлена (и инициализирована) или нет в файле site.pp. В коде шаблона, показанном ниже, предложение if проверяет, было ли оно ранее инициализировано.
<% if @local_users -%>
<%= fail('local_users has to be an array') unless local_users.class == Array -%>
<% else -%>
<% local_users = [ "root" ] -%>
<%# some code to add more users to the array -%>
<% end -%>
<% local_users.uniq.each do |user| -%>
<%= user %>
<% end -%>
Если $local_users не объявлен в файле site.pp (else ветка), этот код работает безупречно. Если он объявлен (если ветвь), то он терпит неудачу при попытке применить манифест Puppet:
Failed to parse template sendmail/local-users.erb: undefined method `uniq' for nil:NilClass at /usr/share/puppet/modules/sendmail/manifests/config.pp:39
(строка 39 — это место, где вызывается шаблон: content => template('sendmail/sendmail.mc.erb'),
)
Проблема в том, что в цикле переменная local_users не распознается как массив. Я решил проблему, просто объявив локальную переменную в ветке if:
<% if @local_users -%>
<%= fail('local_users has to be an array') unless local_users.class == Array -%>
<% local_users = @local_users -%>
<% else -%>
Но внутри ветки if это массив, так как local.users.class == Array
возвращает true (в этот момент я также могу без проблем использовать метод local_users.uniq). Кроме того, я пробовал с if local_users
(без @) и внутри ветки if local_users по-прежнему является массивом, но в цикле продолжаются сбои.
Вот мои вопросы:
- Как можно объяснить такое поведение? Почему переменная local_users представляет собой массив внутри ветки if, а не в цикле?
- Верен ли мой обходной путь или есть лучшие способы сделать это?