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ファイル(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ブランチ内では、trueを返すため、配列になりlocal.users.class == Arrayます(この時点で、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 == Arrayreturn false.

local_userビューに対してローカルな@local_user変数であり、そのビューの背後にあるコントローラーのインスタンス変数です。

when ou invoke を持たないようにするには、local_userに割り当てる必要があるのはそのためです。@local_usernillocal_users.uniq

ところで、コントローラーのすべてのロジックlocal_usersを単純に使用して移動するのではなく、なぜ作業しているのですか?@local_users

于 2012-06-22T11:41:13.073 に答える