Merge a hash with the key/values of a string in ruby
我正在尝试将哈希与ruby中字符串的键/值合并。
即
1 2 3 | h = {:day => 4, :month => 8, :year => 2010} s ="/my/crazy/url/:day/:month/:year" puts s.interpolate(h) |
我发现的全部是迭代键并替换值。但是我不确定是否有更好的方法? :)
1 2 3 4 5 | class String ?def interpolate(e) ? ?self if e.each{|k, v| self.gsub!(":#{k}","#{v}")} ?end end |
谢谢
无需重新发明Ruby内置组件:
1 2 3 | h = {:day => 4, :month => 8, :year => 2010} s ="/my/crazy/url/%{day}/%{month}/%{year}" puts s % h |
(请注意,这需要Ruby 1.9)
"更好"可能是主观的,但是这里的方法仅使用一次对
1 2 3 4 5 | class String def interpolate!(h) self.gsub!(/:(\\w+)/) { h[$1.to_sym] } end end |
因此:
1 2 | >>"/my/crazy/url/:day/:month/:year".interpolate!(h) =>"/my/crazy/url/4/8/2010" |
其他想法可能是扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
这对我来说似乎并不坏,但是另一种方法是使用ERB:
1 2 3 4 5 | 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) |