0

我不理解我在 Puppet 模板 (erb) 中编写的这段 Ruby 代码的行为。它必须与我忽略且无法找出的实例变量的某些属性有关。

在 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 文件(其他分支)中声明,则此代码可以完美运行。如果它被声明(如果是分支),那么在尝试应用 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 分支内部它是一个 Array,因为它local.users.class == Array返回 true (此时我也可以毫无问题地使用方法 local_users.uniq )。此外,我尝试使用if local_users(不带@)并且在 if 分支中 local_users 仍然是一个数组,但在循环中不断失败。

以下是我的问题:

  1. 如何解释这种行为?为什么 local_users 变量是 if 分支内的数组而不是循环?
  2. 我的解决方法是正确的还是有更好的方法来做到这一点?
4

1 回答 1

0

因为在 Rubynil中是一个具有自己的类 ( NilClass) 的对象,并且因为(尝试使用irb):

nil.respond_to? :class
# => true

语句local_users.class == Array返回false

local_user是视图的局部变量,@local_user而是该视图后面的控制器的实例变量。

有两种不同的东西,这就是为什么你必须分配local_userto@local_user才能没有nilwhen ou invoke local_users.uniq

顺便说一句,你为什么要使用local_users而不是简单地使用@local_users和移动控制器上的所有逻辑?

于 2012-06-22T11:41:13.073 回答