Ruby元编程笔记——5.编写代码的代码

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

你可能感兴趣的:(Ruby元编程笔记——5.编写代码的代码)