Объединить хеш с ключом / значениями строки в ruby - PullRequest
6 голосов
/ 26 марта 2010

Я пытаюсь объединить хеш с ключом / значениями строки в ruby.

т.е.

h = {:day => 4, :month => 8, :year => 2010}
s = "/my/crazy/url/:day/:month/:year"
puts s.interpolate(h)

Все, что я нашел, это перебрать ключи и заменить значения. Но я не уверен, есть ли лучший способ сделать это? :)

class String
  def interpolate(e)
    self if e.each{|k, v| self.gsub!(":#{k}", "#{v}")}
  end
end

Спасибо

Ответы [ 4 ]

7 голосов
/ 09 июня 2011

Не нужно заново изобретать встроенные модули Ruby:

h = {:day => 4, :month => 8, :year => 2010}
s = "/my/crazy/url/%{day}/%{month}/%{year}"
puts s % h

(обратите внимание, для этого требуется Ruby 1.9 +)

5 голосов
/ 26 марта 2010

«Лучше», вероятно, субъективно, но вот метод, использующий только один вызов gsub:

class String
  def interpolate!(h)
    self.gsub!(/:(\w+)/) { h[$1.to_sym] }
  end
end

Таким образом:

>> "/my/crazy/url/:day/:month/:year".interpolate!(h)
=> "/my/crazy/url/4/8/2010"
1 голос
/ 27 марта 2010

Дополнительной идеей может быть расширение метода String#%, чтобы он знал, как обрабатывать Hash параметры, сохраняя при этом существующую функциональность:

class String
  alias_method :orig_percent, :%
  def %(e)
    if e.is_a?(Hash)
      # based on Michael's answer
      self.gsub(/:(\w+)/) {e[$1.to_sym]}
    else
      self.orig_percent e
    end
  end
end

s = "/my/%s/%d/:day/:month/:year"
puts s % {:day => 4, :month => 8, :year => 2010}
#=> /my/%s/%d/4/8/2010
puts s % ['test', 5]
#=> /my/test/5/:day/:month/:year
1 голос
/ 26 марта 2010

Это не выглядит плохо для меня, но другой подход будет использовать ERB:

require 'erb'

h = {:day => 4, :month => 8, :year => 2010}
template = ERB.new "/my/crazy/url/<%=h[:day]%>/<%=h[:month]%>/<%=h[:year]%>"
puts template.result(binding)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...