Kernel.eval
eval(string [, binding [, filename [,lineno]]]) → obj
Evaluates the Ruby expression(s) in string. If binding is given, which must be a Binding object, the evaluation is performed in its context. If the optional filename and lineno parameters are present, they will be used when reporting syntax errors.
def get_binding(str)
return binding
end
str = "hello"
eval "str + ' Fred'" #=> "hello Fred"
eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
绑定对象
Binding就是一个用对象表示的完整作用域。你可以通过创建Binding对象来捕获并带走当前的作用域。可以使用Kernel#binding()方法来创建Binding对象。
Ruby提供了一个名为TOPLEVEL_BINDING的预定义常量,它表示顶级作用域的Binding对象。
class MyClass
def my_method
eval "self", TOPLEVEL_BINDING
end
end
MyClass.new.my_method # => main
eval最大问题是安全性,有代码注入隐患。
污染对象和安全级别
Ruby会自动把不安全的对象标记为被污染的。污染对象包括程序从Web表单、文件和命令行读入的字符串,甚至包括系统变量。
tainted?方法判断对象是否被污染。
在任何大于0的安全级别($SAFE)上,Ruby都会拒绝执行污染的字符串。
钩子方法
Class#inherited
Module#included
Module#extended
Module#method_added