评估和绑定:它们有什么用?
eval and binding: what are they useful for?
根据ruby-doc.org,kernel#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
的值。如果我们使用 eval
和 binding
来检索我们已经知道的值,这些方法有什么用?
为了便于讨论,假设您正在使用模板引擎 - 它将处理给定的文本并将其中的 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
根据ruby-doc.org,kernel#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
的值。如果我们使用 eval
和 binding
来检索我们已经知道的值,这些方法有什么用?
为了便于讨论,假设您正在使用模板引擎 - 它将处理给定的文本并将其中的 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