我不明白我在Puppet模板(erb)中编写的这段Ruby代码的行为。它必须与我忽略但无法找到的实例变量的某些属性相关。
在Puppet端,可以在文件site.pp中声明(和初始化)变量$ local_users。在下面显示的模板代码中,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 -%>
如果未在site.pp文件中声明$ local_users(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变量不被识别为Array。我解决了问题,只是在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仍然是一个数组,但是在循环中仍然失败。
以下是我的问题:
答案 0 :(得分:0)
因为在Ruby中nil
是一个具有自己的类(NilClass
)的对象,因此(尝试使用irb
):
nil.respond_to? :class
# => true
声明local_users.class == Array
返回false
。
local_user
是视图的本地变量,而@local_user
是该视图后面的控制器的实例变量。
有两种不同的东西,这就是为什么你必须将local_user
分配给@local_user
,以便在你调用nil
时没有local_users.uniq
。
顺便问一下,你为什么要使用local_users
而不是简单地使用@local_users
并移动控制器上的所有逻辑?