Как сопоставлять и заменять шаблонные теги в Ruby / Rails? - PullRequest
7 голосов
/ 07 июня 2011

Попытка добавить очень простой шаблон описания к одной из моих моделей Rails. То, что я хочу сделать, это взять строку шаблона следующим образом:

template = "{{ name }} is the best {{ occupation }} in {{ city }}."

и такой хеш-код:

vals = {:name => "Joe Smith", :occupation => "birthday clown", :city => "Las Vegas"}

и получите сгенерированное описание. Я думал, что смогу сделать это с простым gsub, но Ruby 1.8.7 не принимает хэши в качестве второго аргумента. Когда я делаю gsub как блок:

> template.gsub(/\{\{\s*(\w+)\s*\}\}/) {|m| vals[m]}
=> " is the best  in ." 

Вы можете видеть, что он заменяет всю строку (с фигурными скобками), а не захватывает совпадения.

Как мне заставить его заменить "{{кое-что}}" на vals ["что-то"] (или vals ["что-то" .to_sym])?

ТИА

Ответы [ 2 ]

24 голосов
/ 07 июня 2011

Использование Ruby 1.9.2

Оператор форматирования строки % отформатирует строку с хешем как arg

>> template = "%{name} is the best %{occupation} in %{city}."
>> vals = {:name => "Joe Smith", :occupation => "birthday clown", :city => "Las Vegas"}
>> template % vals
=> "Joe Smith is the best birthday clown in Las Vegas."

Использование Ruby 1.8.7

Оператор форматирования строки в Ruby 1.8.7 не поддерживает хэши . Вместо этого вы можете использовать те же аргументы, что и в решении Ruby 1.9.2, и исправить объект String, чтобы при обновлении Ruby вам не приходилось редактировать строки.

if RUBY_VERSION < '1.9.2'
  class String
    old_format = instance_method(:%)

    define_method(:%) do |arg|
      if arg.is_a?(Hash)
        self.gsub(/%\{(.*?)\}/) { arg[$1.to_sym] }
      else
        old_format.bind(self).call(arg)
      end
    end
  end
end

>> "%05d" % 123 
=> "00123"
>> "%-5s: %08x" % [ "ID", 123 ]
=> "ID   : 0000007b"
>> template = "%{name} is the best %{occupation} in %{city}."
>> vals = {:name => "Joe Smith", :occupation => "birthday clown", :city => "Las Vegas"}
>> template % vals
=> "Joe Smith is the best birthday clown in Las Vegas."

пример кодовой панели, показывающий стандартное и расширенное поведение

2 голосов
/ 07 июня 2011

Возможно, проще всего использовать $1.to_sym в вашем блоке:

>> template.gsub(/\{\{\s*(\w+)\s*\}\}/) { vals[$1.to_sym] }
=> "Joe Smith is the best birthday clown in Las Vegas."

Из тонкой инструкции :

В блочной форме текущая строка совпадения передается как параметр, и переменные, такие как $ 1, $ 2, $ `, $ & и $’, будут установлены соответствующим образом. Значение, возвращаемое блоком, будет заменено на совпадение при каждом вызове.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...