将方法传递给稍后要插入的字符串

是否可以将字符串传递给ruby中的方法并使该方法插入该字符串?

我有这样的想法:

do_a_search("location = #{location}") ... def do_a_search(search_string) location = .... #get this from another source Model.where(search_string) end 

上下文是RoR,但我认为这是一个普遍的ruby问题。 我意识到上面的例子看起来有点复杂,但我正在尝试重构一堆非常重复的方法。

问题是,如果我将字符串插入双引号中,则在调用方法时位置不存在,如果我将其放在单引号中,它将永远不会被插值…

我真正想要做的是将它放在单引号中并稍后进行插值。 我不认为这是可能的,或者我错过了什么?

编辑:要清楚(因为我认为我已经过度简化了我上面要做的事情),其中一个问题是我可能想在多个上下文中调用此方法; 我可能真的想打电话

 do_a_search("country = #{country}") 

甚至

 do_a_search("country = #{country} AND location = #{location}) 

(国家也作为我方法中的局部变量存在)。 因此,我希望在方法调用中传递替换所需的所有内容

我认为facet gem中的String.interpolate方法可以解决我的问题,但它在rails 4中不起作用

为此目的,使用% 。 首先,创建一个字符串:

 s = "location = %{location}" 

之后,您可以将%应用于它:

 s % {location: "foo"} # => "location = foo" 

如果您不必为参数命名,那么它更简单:

 s = "location = %s" s % "foo" # => "location = foo" 

正如我上面提到的, Facets Gem会对此有所帮助,但似乎不适用于rails 4

但是它扩展String的代码非常简单:

 class String def self.interpolate(&str) eval "%{#{str.call}}", str.binding end end 

我认为实施然后在方法中使用它是做我正在寻找的最明智的方式,但我会接受Sawa的回答,因为正如Paul Richter和Chuck所指出的那样,我认为它会起作用,但是如果我没有完全接听电话那么“爆炸”的风险。

你想要的基本上是一个格式字符串,所以我认为sprintf或%你会更好。

 do_a_search("location = %s") ... def do_a_search(search_string) location = .... #get this from another source Model.where(search_string % location) end 

如果您想要插入多个内容并且不想强制执行订单,则可以使用哈希和命名说明符。

 do_a_search("location = %{location}") ... def do_a_search(search_string) location = .... #get this from another source Model.where(search_string % {location: location}) end 

您可以使用bindingERB来延迟绑定外推:

 require 'erb' def do_a_search(search_string) location = 'this' ERB.new(search_string).result(binding) end do_a_search('location = <%= location %>') # => "location = this" 

或者,您可以直接使用eval

 def do_a_search(search_string) location = 'this' eval search_string, binding end do_a_search('"location = #{location}"') # => "location = this" 

当然,只有在do_a_search中收到的字符串被信任和/或清理时, do_a_search是可接受的。