Chef erubis模板:基于值类的格式输出

时间:2013-11-03 15:14:18

标签: ruby chef erubis

在我的Chef cookbook(对于mailman)中,我想使用一个哈希属性,并包含我想写入模板的所有配置选项(类似于chef-client cookbook中的完成方式)。 / p>

所以我希望拥有我的属性:

default[:myapp][:config] = {
  "I_AM_A_STRING" => "fooo",
  "I_AM_AN_INT" => 123,
  "I_AM_AN_ARRAY" => ["abc", "cde"]
}

作为输出,我想要以下(mailman兼容):

I_AM_A_STRING = 'fooo'
I_AM_AN_INT = 123
I_AM_AN_ARRAY = ['abc', 'cde']

然而,它不起作用。

要调试问题,我在erubis模板中有以下代码:

<% node[:myapp][:config].each_pair do |key, value| -%>
  <% case value.class %>
  <% when Chef::Node::ImmutableArray %>
# <%= key %> is type <%= value.class %>, used when Chef::Node::ImmutableArray
<%= key %> = ['<%= value.join("','") %>']
  <% when Fixnum %>
# <%= key %> is type <%= value.class %>, used when Fixnum
<%= key %> = <%= value %> #fixnum
  <% when String %>
# <%= key %> is type <%= value.class %>, used when String
<%= key %> = '<%= value %>' #string
  <% else %>
# <%= key %> is type <%= value.class %>, used else
<%= key %> = '<%= value %>'
  <% end -%>
<% end -%>

所以我想使用case .. when来区分value.class。但是,when条件都不匹配。所以输出是:

# I_AM_A_STRING is type String, used else
I_AM_A_STRING = 'fooo'
# I_AM_AN_INT is type Fixnum, used else
I_AM_AN_INT = '123'
# I_AM_AN_ARRAY is type Chef::Node::ImmutableArray, used else
I_AM_AN_ARRAY = '["abc", "cde"]'

当我尝试when Whatever.class时,所有类型的第一个when匹配。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

看起来像你的意思

   <% case value %>

而不是

  <% case value.class %>

这就是case .. when在红宝石中的作用。通常情况下,您需要根据值(甚至是一系列值)进行切换,也需要根据类型进行切换。

让你在红宝石中做这样的事情(因此也是在erubis / eruby中):

def f(x)
  case x
    when String then "#{x} is a String"
    when 42 then "It's #{x==42}, x is 42"
    when 21..27 then "#{x} is in 21..27"
    when Fixnum then "#{x} is numeric, that's all I know"
    else "Can't say."
  end
end

f(1)        # "1 is numeric, that's all I know" 
f(25)       # "25 is in 21..27"  
f("hello")  # "hello is a String"
f(false)    # "Can't say."