In my Chef cookbook (for mailman), I want use an attribute that is a hash and contains all the configuration options I want to write into a template (similar to how it's done in the chef-client cookbook).
So I want to have in my attributes:
default[:myapp][:config] = {
"I_AM_A_STRING" => "fooo",
"I_AM_AN_INT" => 123,
"I_AM_AN_ARRAY" => ["abc", "cde"]
}
As output, I want the following (mailman compatible):
I_AM_A_STRING = 'fooo'
I_AM_AN_INT = 123
I_AM_AN_ARRAY = ['abc', 'cde']
However, it does not work.
To debug the problem, I have the following code in my erubis template:
<% 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 -%>
So I want to use the case .. when
to distinguish between value.class
. However, none of the when
conditions matches. So the output is:
# 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 I try when Whatever.class
, the first when
matches for all types.
What am I doing wrong?
Looks like you mean
instead of
That's how
case
..when
works in ruby. It's often the case you need to switch based on value (or even a range of values ), and also on type.It let's you do things like this in ruby (and hence also in erubis/eruby):