шаблон марионетки убрать последнюю запятую

У меня есть следующий шаблон примера марионетки:

{
  "servers" : [ {
    "port" : 9200,
    "host" : "localhost",

    "queries" : [
      <% @markets.each do |market| -%>
      {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_<%= market %>:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
    <% end -%>
    ],
    "numQueryThreads" : 2
  } ],
}

Применяя его с market=['UK','FR','IT'], я получаю следующее:

{
  "servers" : [ {
    "port" : 9200,
    "host" : "localhost",

    "queries" : [
            {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_UK:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
          {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_FR:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
          {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_IT:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
        ],
    "numQueryThreads" : 2
  } ],
}

Проблема в последней запятой, из-за чего получается недопустимая конфигурация solr.

Вместо применения market.each do я мог бы использовать market.map и join(','). но как использовать карту в этом случае?

Я могу использовать карту следующим образом:

<%= @markets.map{ |market| "hello_"+market }.join(',') -%>

это напечатает hello_UK,hello_FR,hello_IT (обратите внимание, что у нас нет запятой после hello_IT), но мне нужно что-то вроде этого:

{
  "servers" : [ {
    "port" : 9200,
    "host" : "localhost",

    "queries" : [
      <% @markets.map |market| -%>
      {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_<%= market %>:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
    <% }.join(',') -%>
    ],
    "numQueryThreads" : 2
  } ],
}

это не работает.

Итак, как заставить его работать? или как изменить мой шаблон марионетки, чтобы удалить последнюю запятую?


person David Portabella    schedule 13.08.2013    source источник
comment
Старый трюк состоит в том, чтобы включить фиксированную фиктивную запись после вашего списка, которая ничего не ломает. Может быть, это вариант.   -  person Thilo    schedule 13.08.2013
comment
Я бы использовал jbuilder   -  person Stefan    schedule 13.08.2013
comment
@Stefan, как бы вы подключили jbuilder к шаблону марионетки?   -  person David Portabella    schedule 13.08.2013
comment
@DavidPortabella Я не знаю Puppet, создание JSON с помощью компоновщика казалось очевидным.   -  person Stefan    schedule 13.08.2013


Ответы (4)


На самом деле это проблема Ruby, а не проблема Puppet. Поскольку это массив, просто измените .each на .each_with_index. Затем вы можете заключить последнюю запятую в проверку, чтобы увидеть, меньше ли текущее значение индекса на единицу, чем размер индекса. Например, следующий код добавляет запятую только в том случае, если текущий market не является последним в массиве:

<% @markets.each_with_index do |market, i| -%>

а потом

}<%= ',' if i < (@markets.size - 1) %>
person itsbruce    schedule 16.08.2013
comment
Я не уверен, почему вы называете это обходным путем; это решение. Puppet использует систему шаблонов ERB (Embedded Ruby), а Ruby — это код, который вы используете для управления шаблонами. Все, что делает Puppet, — это настраивает область видимости переменных и предоставляет несколько вспомогательных функций. Он не может помочь вам с итерацией по массиву — это то, что вам нужно решить в коде Ruby. Рад был помочь в любом случае, конечно. - person itsbruce; 16.08.2013
comment
это работает и решает проблему, и я очень благодарен, что вы поделились этим. однако вы согласитесь со мной, что это уродливый код. возможно, это единственный доступный тип решения, и в этом случае это означает, что erb довольно плохой (например, по сравнению с шаблоном Scala и playframework). или, может быть, есть способ сделать это без этого трюка, может быть, с помощью @markets.map{ |market| ... }.join(','), но я не понял как. - person David Portabella; 16.08.2013
comment
Это некрасиво, я думаю. ERB очень прост — это всего лишь способ оценки Ruby, встроенного в текст, и единственное волшебство, которое он добавляет, — это возможность контролировать нежелательные пробелы ;) Как кодировщик Scala, у вас должно быть достаточно проблем с Puppet DSL, не говоря уже о шаблонах. - person itsbruce; 16.08.2013
comment
не забудьте «делать»: market.each_with_index do |market, i| - person Josh; 12.02.2015

Я видел на сайте puppet labs (https://ask.puppetlabs.com/question/4195/joining-array-from-hieraconcat-other-value-in-erb/) эта форма решения.

<%= quorum.map{ |srv| "#{srv}:#{portNum}" }.join(',') %>

Этот код позволяет вам взять массив и создать вариант каждого элемента, а затем соединить их все вместе с соответствующим текстом соединения (без ложной запятой в конце).

person Ben    schedule 23.10.2014

Для Puppet 4.10.12 ответ Бена у меня не работал, но сработал следующий аналогичный синтаксис.

server=<%= $servers.map |$server| { "${server['hostname']}:${server['port']}" }.join(',') %>
person Ed R.    schedule 20.03.2019

Это проще, если вы сделаете это в обратном порядке. Вместо добавления запятой ко всем разделам, кроме последнего, вы можете префиксировать все разделы, кроме первого, с помощью запятой. Это немного проще реализовать с помощью переменной, которая меняет состояние после первого раздела:

<%- comma = ""; @markets.map |market| -%><%= comma -%>

...

<%- comma = "," -%>
<%- } -%>
person chutz    schedule 24.07.2020