title: Ruby instance variable in a Puppet template (erb)
body: <p>I do not understand the behaviour of this Ruby code I have written inside a Puppet template (erb). It must be related to some property of instance variables that I ignore and have not been able to find out.</p>
  
  <p>At the Puppet side a variable $local_users can be declared (and initialized) or not in the file site.pp. In the template code shown below, the if sentence checks if it has been previously initialized.</p>
  
  <pre><code>&lt;% if @local_users -%&gt;
    &lt;%= fail('local_users has to be an array') unless local_users.class == Array -%&gt;
  &lt;% else -%&gt;
    &lt;% local_users = [ "root" ] -%&gt;
    &lt;%# some code to add more users to the array -%&gt;
  &lt;% end -%&gt;
  &lt;% local_users.uniq.each do |user| -%&gt;
    &lt;%= user %&gt;
  &lt;% end -%&gt;
  </code></pre>
  
  <p>If $local_users is not declared in the site.pp file (else branch), this code works flawlessly. If it is declared (if branch), then it fails when trying to apply the Puppet manifest:</p>
  
  <pre><code>Failed to parse template sendmail/local-users.erb: undefined method `uniq' for nil:NilClass at /usr/share/puppet/modules/sendmail/manifests/config.pp:39
  </code></pre>
  
  <p>(line 39 is where the template is invoked: <code>content =&gt; template('sendmail/sendmail.mc.erb'),</code>)</p>
  
  <p>The problem is that in the loop the local_users variable is not recognized as an Array. I solved the problem just declaring a local variable at the if branch:</p>
  
  <pre><code>&lt;% if @local_users -%&gt;
    &lt;%= fail('local_users has to be an array') unless local_users.class == Array -%&gt;
    &lt;% local_users = @local_users -%&gt;
  &lt;% else -%&gt;
  </code></pre>
  
  <p>But inside the if branch <strong>it is an Array</strong>, since <code>local.users.class == Array</code> returns true (at this point I can use the method local_users.uniq too without problems). Furthermore, I have tried with <code>if local_users</code> (without @) and inside the if branch local_users is still an Array, but in the loop keeps failing.</p>
  
  <p>Here are my questions:</p>
  
  <ol>
  <li>How can this behaviour be explained? Why is the local_users variable an Array inside the if branch and not at the loop?</li>
  <li>Is my workaround correct or are there better ways to do this?</li>
  </ol>