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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.