元编程

元编程的概念

元编程(Metaprogramming是指某类计算机程序的编写,这类计算机程序编写或者操纵其他程序(或者自身)作为它们的数据,或者在编译时完成部分本应在运行时完成的工作。很多情况下比手工编写全部代码相比工作效率更高。编写元程序的语言称之为元语言,被操作的语言称之为目标语言。一门语言同时也是自身的元语言的能力称之为反射

反射是促进元编程的一种很有价值的语言特性。把编程语言自身作为头等对象(如LispRebol)也很有用。支持泛型编程的语言也使用元编程能力。

元编程通常有两种方式起作用。一种方式是通过应用程序接口API)来暴露运行时引擎的内部信息。另一种方法是动态执行包含编程命令的字符串。因此,程序能编写程序。虽然两种方法都能用,但大多数方法主要靠其中一种。

编辑本段发展

元编程在1994年初露端倪,由一个叫 Erwin Unruh 的人首先发现。在1994年,C++标准委员会在圣迭戈(SanDiego)举行的一次会议期间, Erwin Unruh展示了一段特别的代码。这段代码的特别之处在于程序的功能在编译期实现而非运行期,编译器错误信息的方式产生从2到某个给定值之间的所有质数。同年夏天, Todd Veldhuizen Erwin 的例子启发,发现可以使用C++模板进行元编程元编程,并发表了一份技术报告。

编辑本段使用示例

一个简单元编程的例子是使用bash脚本产生式编程示例:

#!/bin/bash

# metaprogram

echo '#!/bin/bash' >program

for ((I=1; I<=992; I++)) do

echo "echo $I" >>program

done

chmod +x program

这个脚本(或程序)生成了一个新的993行程序来打印1992。这只是演示用代码来写更多代码,并不是打印数字的最有效方法。然而,一个程序员可以几分钟内编写和执行元程序,却生成了近1000行代码。

==========

C++中也可以使用模板来进行元编程(以下代码在VC2008中编译通过):

#include<iostream>

using namespace std;

int Result;

//主模板

template<int N> //模板

class Fibonacci

{

public:

enum{Result = Fibonacci<N-1>::Result + Fibonacci<N-2>::Result };

//枚举,带有隐含计算

};

//完全特化模板

template<>

class Fibonacci<1> //带常参数1构造函数

{

public:

enum { Result = 1 };

//给枚举赋初值1

};

//完全特化模板

template<>

class Fibonacci<0> //带参数0的模板

{

public:

enum { Result = 0 };

//给枚举赋初值0

};

int main()

{

std::cout << "20项的Fibonacci数是:" << Fibonacci<20>::Result << std::endl;

//隐含计算

system("pause");

return 1;

}

该示例定义了一个类模板,类中声明了一个枚举类型,该程序的奥秘就在枚举类型的构造上。从枚举类型的构造可以看出,他自身有一个样俺的迭代计算。两个构造函数为枚举类型初始化了数列的初始值,当调用Fibonacci<20>::Reasult时,就以这两个初始值为基础进行迭代。因此,程序在运行时并没有显示的计算,而是在编译时就由编译器计算了。

编译器实例化Fibonacci<20>时,为了给其enum Result赋值,编译器需要对Fibonacci<19>Fibonacci<18>进行实例化,之后同理······,当实例化到Fibonacci<1>Fibonacci<0>的时候,完全特化模板被实例化,至此迭代结束。

所以,该程序编译的结果仅包含一个常量值,输出如下:

20项的Fibonacci数是:6765

==========

不是所有的元编程都用产生式编程。如果程序可以在运行时改变(如LispRubyPythonSmalltalkLuaGroovyJavaScript),这种技术可以不实际生成源代码就使用元编程。

Ruby中,最常用的就是attr系列方法,譬如attrattr_readerattr_writerattr_accessorattr_reader方法为一个实例变量产生一个用于读取其值的方法,attr_writer为其产生一个用于写入值的方法,attr_accessor则同时具有这两种功能。

class Foo

attr_reader :just_read

attr_writer :just_write

attr_accessor :both_read_and_write

def initialize

@just_read = 0

@just_write = 0

@both_read_and_write = 0

end

end

输出attr系列方法生成的方法

puts Foo.instance_methods - Foo.superclass.instance_methods

最常用的元编程工具是编译器,把高级语言转换为汇编语言或机器语言。更灵活的方法是在程序中嵌入解释器直接处理程序数据。有一些实现例如为Object Pascal编写的RemObject's Pascal Script

另一个很常用的元编程例子是lexyacc,用来生成词法分析器语法分析器Yacc通常用作编译器的编译器,生成一个把高级语言转换为机器语言的工具。

quine是一种源代码等于输出的特殊的元程序

面向语言的程序设计是一种强烈关注元编程的编程风格,通过领域特定语言来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值