Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use ":template"-type strings in ruby?

Both rails routes and whenever and a few other things I can't remember have a user-specified template string like so:

template_str = "I am going to :place at :time"

And then there's some magic function which embeds data in place of :place and :time, like so:

template_str.magic_embed_function(place: 'bed', time: '10 pm') 
#=> "I am going to bed at 10 pm"

How can I do this in my ruby projects? Is there a gem that implements String#magic_embed_function?

like image 938
Shelvacu Avatar asked Jul 16 '26 08:07

Shelvacu


2 Answers

Use Percent-Style Interpolation

There is a special type of interpolation that uses the String#% method. This allows you to interpolate ordinal (Array) and non-ordinal (Hash) inputs into a format string similar to that provided by Kernel#sprintf. However, the use of a hash argument with this method enables support for named variables in the format string. As a minimalist example:

"%{foo} %{bar}" % {foo: 'baz', bar: 'quux'}
#=> "baz quux"

With a hash argument, the format-string placeholders are treated as hash keys to be replaced by the associated values in your hash. This makes the order of the variables passed in unimportant. Based on the code in your original post, you could use it as follows:

template_str = 'I am going to %{place} at %{time}.'
template_str % {time: '10:00 PM', place: 'bed'}
#=> "I am going to bed at 10:00 PM."

This is a useful technique when you want to pass an array or hash for interpolation, but may or may not offer advantages over other types of interpolation in the general case. Your mileage may vary.

like image 115
Todd A. Jacobs Avatar answered Jul 17 '26 21:07

Todd A. Jacobs


I extended String class with a magic_embed_function as you asked..rs It's very simple, first we split our string and collect the words and check if matches with this simple regex for symbols, basically says "if something starts with : , that's a symbol", after we found a symbol we replace using gsub! (global substitution, with the bang to change our object) passing our symbol as first param and the param received that corresponds to that symbol and at the end we return self, to return the string that called the method.

template_str = "I am goind to :place at :time"

class String
    def magic_embed_function(params)
        self.split(" ").collect do |value|
            if value =~ /:.*/
                self.gsub! value, params[value[1..value.length].to_sym]
            end
        end
        self
    end
end

p template_str.magic_embed_function({place: "bed", time: "10 pm"})

#"I am goind to bed at 10 pm"
like image 25
Marcle Rodrigues Avatar answered Jul 17 '26 21:07

Marcle Rodrigues