2

私はRuby初心者ですが、スクリプトと大量の合成データ(Yamlファイルなどに入れます)を使用してPuppet .erbテンプレートをレンダリングしようとしています。私たちの人形テンプレートは、主に次のようなものです。

# Some config file
<%= @some_ordinary_variable %>
<%= some_other_variable %>
<%= @something_undefined %>
<%= scope.function_hiera("some_hiera_variable") %>

私はhieraルックアップをモックアップするところまで持っており、「some_other_variable」を代用する方法としてERBでOpenStructを使用する問題を見つけました(「@some_ordinary_variable」を機能させることに少し行き詰まっていますが、それを理解することができます。

私が尋ねているのは、各変数ルックアップで少しのコードを実行できるバインディングをどのように使用できるかということです。私は次のようなものを実行したいと考えています:

def variable_lookup(key)
  if @variables.has_key?(key)
    return @variables[key]
  else
    warn "The variable " + key + " is required by the template but not set"
  end
end

次に、これを Hiera モックアップとマージして、Hiera データを検索します。私がこれまでに持っているコードは次のとおりです。

require 'rubygems'
require 'yaml'
require 'erb'
require 'ostruct'

class ErbBinding < OpenStruct
  include Enumerable
  attr_accessor :yamlfile, :hiera_config, :erbfile, :yaml

  def scope
    self
  end

  def function_hiera(key)
    val = @yaml['values'][key]
    if val.is_a?(YAML::Syck::Scalar)
      return val.value
    else
      warn "erby: " + key + " required in template but not set in yaml"
      return nil
    end
  end

  def get_binding
    return binding()
  end
end

variables = {'some_other_variable' => 'hello world'}

hs = ErbBinding.new(variables)
template = File.read('./template.erb')
hs.yaml = YAML.parse( File.read('./data.yaml') )

erb = ERB.new(template)

vars_binding = hs.send(:get_binding)
puts erb.result(vars_binding)

「変数」ハッシュを使用するだけでなく、コードを実行するバインディングをセットアップする方法がわかりません。何か案は?

4

1 に答える 1

1

これは驚くほど簡単であることがわかりました!特別なメソッド「method_missing」を使用して、定義されていないすべてのメソッド呼び出しをすくい上げることができることがわかりました。つまり、バインディングを使用してハッシュをオブジェクトにします (各ハッシュ キーがオブジェクトのメソッドになります)。メソッドが欠落している場合 (つまり、ハッシュにキーが設定されていない場合)、Ruby は「method_missing」を呼び出します。ここで重要な情報が見つかった場合: http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

あなたが疑問に思っているなら、これが私がこれまでに持っているコードの合計です...

require 'rubygems'
require 'yaml'
require 'erb'
require 'ostruct'

class ErbBinding < OpenStruct
  include Enumerable
  attr_accessor :yamlfile, :hiera_config, :erbfile, :yaml

  def method_missing(m, *args, &block)
    warn "erby: Variable #{m} required but not set in yaml"
  end

  def scope
    self
  end

  def function_hiera(key)
    val = @yaml['values'][key]
    if val.is_a?(YAML::Syck::Scalar)
      return val.value
    else
      warn "erby: " + key + " required in template but not set in yaml"
      return nil
    end
  end

  def get_binding
    return binding()
  end
end

variables = {'some_other_variable' => 'hello world'}

hs = ErbBinding.new(variables)
template = File.read('./template.erb')
hs.yaml = YAML.parse( File.read('./data.yaml') )

erb = ERB.new(template)

vars_binding = hs.send(:get_binding)
puts erb.result(vars_binding)

このコードはまだ <%= @variable %> のようなテンプレートを処理しませんが、元の質問の他の 2 つのケースは処理します。

于 2013-02-15T17:48:45.280 に答える