2012-06-22 24 views
0

我不明白我在Puppet模板(erb)中編寫的這段Ruby代碼的行爲。它必須與我忽略的實例變量的某些屬性相關,並且無法找到。Puppet模板中的Ruby實例變量(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 -%> 

如果在site.pp文件(else分支)中未聲明$ local_users,則此代碼完美無缺地工作。如果宣佈(如分公司),然後嘗試應用木偶清單時失敗:

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 @local_users -%> 
    <%= fail('local_users has to be an array') unless local_users.class == Array -%> 
    <% local_users = @local_users -%> 
<% else -%> 

但裏面如果分支爲Array,因爲local.users.class == Array真(在這一點上,我可以使用的方法local_users.uniq太沒有什麼問題)。此外,我嘗試了if local_users(不帶@),並且在if分支中local_users仍然是一個Array,但是在循環中保持失敗。

這裏是我的問題:

  1. 怎麼能這種行爲來解釋?爲什麼local_users在if分支中而不是在循環中變量數組?
  2. 我的解決方法是否正確或者是否有更好的方法來執行此操作?

回答

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並移動控制器上的所有邏輯?

+0

我很確定Puppet沒有控制器...... –

+0

Ops,你是對的:這個提示只有在強大的MVC架構上纔有意義。 所有其餘的依然存在。 –

+0

謝謝@andrea。正如@mark所說,我不認爲在這種情況下「控制器」是最好的術語。根據定義,實例變量屬於創建它的對象本身(即self)。在這種情況下,自我就是整個模板。無論如何,讓我重申一下我所指的奇怪行爲:如果我把'test_class = local_users.uniq'放在if分支中,它就行得通(即local_users.class是Array)!這就好像局部變量的範圍是if分支... – Christian