如何在ruby中使用“:template”类型的字符串?

时间:2016-03-18 00:02:29

标签: ruby replace

两个rails路由以及我记不起的其他一些东西都有一个用户指定的模板字符串,如下所示:

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

然后有一些神奇的功能将数据嵌入:place:time,如下所示:

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

我如何在我的ruby项目中执行此操作?是否有一个实现String#magic_embed_function的宝石?

2 个答案:

答案 0 :(得分:4)

使用百分比样式插值

有一种特殊类型的插值使用String#%方法。这允许您将序数(Array)和非序数(Hash)输入插入到类似于Kernel#sprintf提供的格式字符串中。但是,在此方法中使用散列参数可以支持格式字符串中的命名变量。作为极简主义的例子:

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

使用哈希参数,格式字符串占位符被视为哈希键,将被哈希中的关联值替换。这使得传递的变量的顺序变得不重要。根据原始帖子中的代码,您可以按如下方式使用它:

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."

当您想要传递数组或散列进行插值时,这是一种有用的技术,但在一般情况下可能会或可能不会提供优于其他类型插值的优势。您的里程可能会有所不同。

答案 1 :(得分:1)

我按照你的要求扩展了带有magic_embed_function的String类 这很简单,首先我们分割我们的字符串并收集单词并检查是否与符号的这个简单正则表达式匹配,基本上说"如果有东西以:,那个' sa符号",在我们找到符号后,我们用gsub替换! (全局替换,用bang来改变我们的对象)将我们的符号作为第一个参数传递,并且收到的参数对应于该符号,最后我们返回self,返回调用该方法的字符串。

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"