【问题标题】:Populating ERB template with hash fails with symbol as array index使用哈希填充 ERB 模板失败,符号作为数组索引
【发布时间】:2015-06-11 08:46:27
【问题描述】:

我正在尝试使用内置在厨师食谱中的哈希填充 json 字符串,但一直遇到错误“符号作为数组索引”。我在 stackoverflow 和谷歌上的搜索让我无处可去,我只是好奇这里发生了什么。我对 Ruby 不是很好,所以如果代码有点不对,请原谅我。

属性文件:

node.default[:server][:sumologic][:sources][:apache] = Hash.new
node.default[:server][:sumologic][:sources][:apache][:type] = "LocalFile"
node.default[:server][:sumologic][:sources][:apache][:name] = "Apache Logs"
node.default[:server][:sumologic][:sources][:apache][:path_expression] = "/var/log/httpd/*.log"
node.default[:server][:sumologic][:sources][:apache][:blacklist] = Array.new
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/access.log*"
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/error.log*"
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/ssl_request_log"
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/access_log"
node.default[:server][:sumologic][:sources][:apache][:blacklist] << "/var/log/httpd/error_log"
node.default[:server][:sumologic][:sources][:apache][:category] = "test-httpd"

模板erb文件:

{
  "api.version": "v1",
  "sources": [
    <% sources.each do |source| %>
    {
      "sourceType" : "<%= source[:type] %>",
      "name": "<%= source[:name] %>",
      "pathExpression": "<%= source[:path_expression] %>",
      <% if defined?(source[:blacklist]) %>
      "blacklist": [
        <% source[:blacklist].each do |listed, index| %>
        <%  if index < source[:blacklist].length - 1 %>
        "<%= listed %>",
        <%  else %>
        "<%= listed %>"
        <%  end %>
        <% end %>
      ],
      <% end %>
      "category": "<%= source[:category] %>"
    },
    <% end %>

...

配方代码:

template '/opt/SumoCollector/sources.json' do
  source 'sources.json.erb'
  variables({
      :sources => node[:server][:sumologic][:sources]
  })
end

【问题讨论】:

    标签: ruby chef-infra


    【解决方案1】:

    您对厨师属性的使用有点错误。它们不是哈希,而是更智能,因此您不必将它们初始化为哈希。 删除行:

    node.default[:server][:sumologic][:sources][:apache] = Hash.new
    

    另外最好在1个操作中初始化数组属性:

    node.default[:server][:sumologic][:sources][:apache][:blacklist] = [
      '/var/log/httpd/access.log*',
      '/var/log/httpd/error.log*',
      '/var/log/httpd/ssl_request_log',
      '/var/log/httpd/access_log',
      '/var/log/httpd/error_log'
    ]
    

    您的错误“作为数组索引的符号”来自您的情况

    <% sources.each do |source| %>
      "sourceType" : "<%= source[:type] %>",
      [...]
    <% end %>
    

    source 实际上是一个数组[:apache, &lt;hash-like-object&gt;],所以调用source[:type] 失败。

    sources 实际上是一个类似哈希的属性集合,您应该相应地处理它。如果你把这条线改成那样

    <% sources.each do |key, source| %>
    

    一切都会奏效。这里 key 将是 ":apache" 而 source 将等于 node[:server][:sumologic][:sources][:apache]

    【讨论】:

    • OP已经显示了,是模板资源的变量属性。传递给 erb 模板的那些变量对于模板实例来说是本地的,语法是 @source[] 来访问它们(我不确定它在全局范围内提供了什么。)
    • 感谢您的解释,我已阅读并了解了更多我在做什么。一切正常,但我在使用 source[:blacklist] 访问黑名单时遇到问题。 puts source[:blacklist] 给了我一个数组 "[\"/var/log/httpd/access.log*\", \"/var/log/httpd/error.log*\", \"/var/log/httpd/ssl_request_log\", \"/var/log/httpd/access_log\", \"/var/log/httpd/error_log\"]" 所以我现在正在解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    相关资源
    最近更新 更多