簡體   English   中英

來自哈希的Ruby .erb模板,但捕獲未設置的變量

[英]Ruby .erb template from hash, but catch unset variables

我有點像Ruby新手,但是我試圖使用腳本和大量合成數據(將其放入Yaml文件或其他內容)來渲染Puppet .erb模板。 我們的人偶模板主要遵循以下幾類原則:

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

我已經盡可能地模擬了層查詢,並發現使用帶有ERB的OpenStruct和 “ some_other_variable”的替代方法來解決問題 (我有點想讓“ @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)

我不能弄清楚如何設置一個運行代碼的綁定,而不僅僅是使用“變量”哈希。 有任何想法嗎?

事實證明這非常簡單! 我發現您可以使用特殊方法“ 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%>這樣的模板,但是它將處理我原始問題中的其他兩種情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM