How to delay ruby evaluation until runtime?


#1

I have a chef template that needs to be placed in 6 directories. 2 of those directories don’t always exist.

The following code works, but requires 2 chef runs because the ‘if’ statement is evaluated at compile time, before the directory exists.

dirs = [ "c:/iis/AAA/bin", c:/iis/BBB/bin", "c:/iis/CCC/bin", "c:/iis/DDD/bin" ]
dirs << "c:/iis/EEE/bin" if File.directory?("c:/iis/EEE")
dirs << "c:/iis/FFF/bin" if File.directory?("c:/iis/FFF")

dirs.each do |dir|
  template "#{dir}/foo.xml" do
    source 'foo.xml.erb'
    action :create
  end
end

How can I delay the evaluation if File.directory?("c:/iis/EEE") until runtime?
I know ruby/chef can do lazy evaluation, but I get “unexpected token” when trying to wrap the if statement in a lazy block.

dirs << "c:/iis/EEE/bin" lazy { if File.directory?("c:/iis/EEE") }

#2

Found a better solution. Let the chef resource handle the if statements with a guard interpreter.

dirs = [ "c:/iis/AAA/bin", c:/iis/BBB/bin", "c:/iis/CCC/bin", "c:/iis/DDD/bin","c:/iis/EEE/bin", "c:/iis/FFF/bin" ]

dirs.each do |dir|
  template "#{dir}/foo.xml" do
    source 'foo.xml.erb'
    action :create
    only_if {  if File.directory?("c:/iis/EEE") }
  end
end