如何在Ruby中进行“后期”字符串插值

>> string = '#{var}' => "\#{var}" >> proc = Proc.new { |var| string } => # >> proc.call(123) => "\#{var}" 

不是我想要的。 string周围的双引号会导致明显的undefined local variable

虽然这是可能的,但如果你不打算使用eval ,那么你打算如何使用它并不会起作用,而且如果有另一种选择,通常这是一个坏主意。 好消息是你有几种选择。

最简单的方法是使用sprintf格式化,使用String#%方法更容易:

 string = '%s' proc = Proc.new { |var| string % var } proc.call(123) # => "123" 

这是一个非常可靠的方法,因为支持.to_s方法的任何东西都可以工作,并且如果它包含可执行代码,则不会导致Universe内爆。

在我的情况下,我需要将配置存储在yml中,使用插值,但只在我需要时进行插值。 Proc接受的答案对我来说似乎过于复杂。

在ruby 1.8.7中,您可以使用%语法,如下所示:

 "This is a %s verb, %s" % ["nice", "woaaaah"] 

当使用至少ruby 1.9.x(或带有i18n的ruby1.8.7)时,有一个更清洁的选择:

 my_template = "This is a %{adjective} verb, %{super}!" my_template % { adjective: "nice", super: "woah" } => "This is a nice verb, woah!" 

它适用于eval:

 proc = Proc.new { |var| eval(%Q{"#{string}"}) } 

(如果您信任string的值。)

您可以通过创建“curried”函数(即:返回Proc的Proc)来实现您正在寻找的DRY,其中内部函数包含基本字符串,其中每个部分的变量都不同。

如果我错了,请纠正我,但是在你的评论链接后面的代码中,两个字符串之间的唯一区别是最后一个字符。 (即使不是,您仍然可以使用此技术来实现相同的目标。)您可以创建一个Proc,它返回包含您的字符串的Proc,然后为两个尾随字符调用外部Proc两次:

 rails_root = "whatever" # Not variant for the string rails_env_prompt = "whatever" #not variant for the string spec = Proc.new { |tail_char| Proc.new {|obj, nest_level, *| "#{rails_root} #{rails_env_prompt} #{obj}:#{nest_level}#{tail_char} " } } Pry.config.prompt = [ spec.call(">"), spec.call("*") ] Pry.config.prompt[0].call("My obj", "My Nest Level") # result: "whatever whatever My obj:My Nest Level> " 

您是否必须在Proc之外定义插值轴承字符串?

 proc = Proc.new { |var| "#{var}" } proc.call(123) # "123" 

这将是我认为最干净的方式。