自修改程序

在大多数编译语言和许多解释语言中,编写和运行程序是两个完全不同的操作。换句话说,你编写的代码是固定的,并且没有程序运行时更改的可能性。

Ruby 的情况并非如此。Ruby程序 - 它的实际代码 - 可以在程序运行时进行修改。甚至可以在运行时输入新的 Ruby 代码并执行新代码而无需重新启动程序。

将数据视为可执行代码的能力称为元编程( meta-programming)。在本书中,我们一直在进行元编程,尽管是一种相当简单的编程。每次在双引号字符串中嵌入表达式时,你都在进行元编程。毕竟,嵌入式表达式并不是真正的程序代码 - 它是一个字符串 - 然而 Ruby 显然必须“将其转换为”程序代码才能够对其进行计算执行。

大多数情况下,你可能会在双引号字符串中的 #{} 分隔符之间嵌入相当简单的代码。通常你可以嵌入变量名,或数学表达式:

str_eval.rb
  1. aStr = 'hello world'
  2. puts( "#{aStr}" )
  3. puts( "#{2*10}" )

但是你不仅限于这种简单的表达方式。如果你愿意,你可以将任何东西嵌入双引号字符串中。实际上,你可以用字符串编写整个程序。你甚至不需要使用 printputs 显示最终结果。只需将双引号字符串放入程序中就会使得 Ruby 对其进行计算执行:

  1. "#{def x(s)
  2. puts(s.reverse)
  3. end;
  4. (1..3).each{x(aStr)}}"

在字符串中编写整个程序可能是一个非常毫无意义的努力。但是,在其它情况下,这种类似的特性可以更有效地使用。例如,Rails 框架广泛使用元编程。你可以使用元编程来探索人工智能和“机器学习”(machine learning)。实际上,任何因程序执行过程中由于交互而修改程序行为进而受益的应用程序本质上都是元编程。

动态(元编程)特性在 Ruby 中无处不在。例如,思考属性访问器:将符号(例如 :aValue)传递给 attr_accessor 方法会最终创建两个方法(aValueaValue=)。