评估和绑定:它们有什么用?

eval and binding: what are they useful for?

根据ruby-doc.orgkernel#eval将绑定对象作为第二个参数如下:

Const = 7
p eval("Const", binding)  # => 7

方法 eval 可以与接受一个参数的方法 get_binding 返回的对象一起使用:

def get_binding(param)
  return binding
end
n = get_binding(7)
p eval("param", n)  # => 7

在第一段代码中,我们得到了Const的值,在第二段代码中,我们得到了param的值。如果我们使用 evalbinding 来检索我们已经知道的值,这些方法有什么用?

为了便于讨论,假设您正在使用模板引擎 - 它将处理给定的文本并将其中的 Ruby 代码替换为它的值。我们可以为此使用 eval

作为通用引擎,模板文本应允许使用 Ruby 变量,其值将在调用者的绑定中定义。在这种情况下,通过将绑定传递给 eval,我们可以允许用户的绑定用于变量评估。

下面演示了一种基本的、不优雅的方法:

template = "Hello @first_name@ @last_name@"

def process(template, b)
    vars = template.scan(/@(\w+)@/).flatten
    vars.each {|v| template = template.gsub("@#{v}@", eval("#{v}", b)) }
    return template
end

first_name = "Wand"
last_name = "Maker"

str = process(template, binding)
p str
#=> "Hello Wand Maker"

first_name = "Rubeus"
last_name = "Hagrid"
p process(template, binding)
#=> "Hello Rubeus Hagrid"

Ruby 的内置模板引擎 ERB 中使用了一种有点类似的方法。你可以看看source code