从Ruby中的变量构建字符串

时间:2017-02-03 15:38:00

标签: ruby chef

在厨师环境中,对于食谱,我有这些数组:

"envs": ["ci","ui","qa"],
"services": ["service_a","service_b","service_c","service_x"]

在模板文件中我使用:

<% @envs.each do |env| %>
file {
  <%
    logfiles = ""
    @services.each do |service|
      logfiles = logfiles + "\"" + "/remotelogs/" + @env + "/" + @service + "_syslog.log\", "
    end
    logfiles = logfiles.chomp(", ")
  %>
  path           => [<%= logfiles %>]    
}
 <% end %>

我得到的错误是:

no implicit conversion of nil into String
...
Template Context:
-----------------
on line #7
  5:       logfiles = ""
  6:       @services.each do |service|
  7:         logfiles = logfiles + "\"" + "/remotelogs/" + @env + "/" + @service + "_syslog.log\", "
  8:       end
  9:         logfiles = logfiles.chomp(", ")
 (erubis):7:in `+'
 (erubis):7:in `block (3 levels) in evaluate'
 (erubis):6:in `each'
 (erubis):6:in `block (2 levels) in evaluate'
 (erubis):2:in `each'
 (erubis):2:in `block in evaluate'

谁能告诉我我做错了什么?我猜测我的引号并没有很好地逃脱?

最终结果应该是三行(每个环境一个),并且对于每个行,路径应该具有值:

path           => ["/remotelogs/ci/service_a_syslog.log", "/remotelogs/ci/service_b_syslog.log", "/remotelogs/ci/service_c_syslog.log", "/remotelogs/ci/service_x_syslog.log"]

2 个答案:

答案 0 :(得分:5)

在这一行

env

应该是@env,而不是service。请注意,logfiles += "\"/remotelogs/#{env}/#{service}_syslog.log\", " 也是如此。这是更好的

logfiles += %{"/remotelogs/#{env}/#{service}_syslog.log", }

或者如果您不想转义双引号,可以使用percent string literals

NaN

答案 1 :(得分:3)

如果我正确理解了您的代码,那么您正尝试重新实现join,但您只需要inspect

@envs = ["ci","ui","qa"]
@services = ["service_a","service_b","service_c","service_x"]

@envs.each do |env|
  logfiles = @services.map{|service|
    "/remotelogs/#{env}/#{service}_syslog.log"
  }
  puts logfiles.inspect
end

输出:

["/remotelogs/ci/service_a_syslog.log", "/remotelogs/ci/service_b_syslog.log", "/remotelogs/ci/service_c_syslog.log", "/remotelogs/ci/service_x_syslog.log"]
["/remotelogs/ui/service_a_syslog.log", "/remotelogs/ui/service_b_syslog.log", "/remotelogs/ui/service_c_syslog.log", "/remotelogs/ui/service_x_syslog.log"]
["/remotelogs/qa/service_a_syslog.log", "/remotelogs/qa/service_b_syslog.log", "/remotelogs/qa/service_c_syslog.log", "/remotelogs/qa/service_x_syslog.log"]

根据您的ERB模板,它变为:

<% @envs.each do |env| %>
file {
  <%
    logfiles = @services.map{|service|
      "/remotelogs/#{env}/#{service}_syslog.log"
    }
  %>
  path           => <%= logfiles.inspect %>
}
<% end %>