Trying to add a very rudimentary description template to one of my Rails models. What I want to do is take a template string like this:
template = "{{ name }} is the best {{ occupation }} in {{ city }}."
and a hash like this:
vals = {:name => "Joe Smith", :occupation => "birthday clown", :city => "Las Vegas"}
and get a description generated. I thought I could do this with a simple gsub but Ruby 1.8.7 doesn't accept hashes as the second argument. When I do a gsub as a block like this:
> template.gsub(/\{\{\s*(\w+)\s*\}\}/) {|m| vals[m]}
=> " is the best in ."
You can see it replaces it with the entire string (with curly braces), not the match captures.
How do I get it to replace "{{ something }}" with vals["something"] (or vals["something".to_sym])?
TIA
The string formatting operator %
will format a string with a hash as the 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."
The string formatting operator in Ruby 1.8.7 doesn't support hashes. Instead, you can use the same arguments as the Ruby 1.9.2 solution and patch the String object so when you upgrade Ruby you won't have to edit your strings.
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."
The easiest thing is probably to use $1.to_sym
in your block:
>> template.gsub(/\{\{\s*(\w+)\s*\}\}/) { vals[$1.to_sym] }
=> "Joe Smith is the best birthday clown in Las Vegas."
From the fine manual:
In the block form, the current match string is passed in as a parameter, and variables such as $1, $2, $`, $&, and $’ will be set appropriately. The value returned by the block will be substituted for the match on each call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With