用 REXX 编写用于 DB2 Universal Database 的脚本: 快速学习 REXX
2008-11-10 16:32:18 来源:WEB开发网简介
如果您在 IBM 操作系统下编写过程序,那么肯定听说过 Rexx。Rexx 是 IBM 随其大型主机、中型操作系统和更低端操作系统一起捆绑的脚本和命令语言。您可能不清楚的是,Rexx 几乎可以在世界上各种其他的操作系统上运行。您可以免费下载用于各版本的 Windows®、Linux、UNIX®、BSD、Mac OS 和 DOS 以及很多其他系统的 Rexx。它甚至可以在用于手持设备的三大主流操作系统 Windows CE、Palm OS 和 Symbian/EPOC32 上运行。
这意味着,如果您学习 Rexx,就可以知道一种可以在从大型主机到手持设备的各种地方运行的脚本语言。Rexx 是一种通用的语言,它强大得足以适合大型主机,但是又灵活得足以适合其他平台。最棒的是,Rexx 容易学习。
在本文中,我将对 Rexx 作一个简要的介绍,作为使用它访问 IBM DB2 UDB 数据的基础。(在后续的文章中,我将给出并讨论更多的 Rexx 脚本示例,以便更深入地解释如何专门为 DB2 应用程序编写 Rexx 脚本。)我将对 Rexx 语言进行概述,并展示学习 Rexx 语言是多么的容易。我还将描述很多可用的免费和开放源码的 Rexx 解释器,并告诉您在哪里可以下载这些解释器。最重要的是,我将为您指出 Web 上提供的其他免费信息来源(参阅参考资料)。在几天时间内,您可以学习使用 Rexx 编程,Rexx 是一种脚本语言,适用于几乎任何编程问题,并且几乎可以在任何机器上运行。
快速了解 Rexx
您已经知道 Rexx 容易学习,那么现在就来验证一下吧。下面是一个完整的 Rexx 脚本:
input = 'invoice_file.txt' /* Name the input file */
do while lines(input) > 0 /* Do while "lines to read" */
input_line = linein(input) /* Read in the next line */
if pos("INVOICE OVERDUE", input_line) > 0 then
say "Found it! Here's where:" input_line
else
say "Not found in this line:" input_line
end
这个脚本从一个输入文件读取所有的行,每次读取一行,并扫描各行,以发现短语 INVOICE OVERDUE。如果该脚本发现了这个短语,则写出一条消息以及短语所在的行。它还通过一条合适的 "not found" 消息显示被排除的行。
在该脚本中,第一行将输入文件的名称(这里是 invoice_file.txt)赋给一个名为 input 的变量。这是一个简单的赋值语句,与大多数编程语言中的一样。在 Rexx 中,赋给变量的字符串或文字可以用单引号或双引号括起来:
input = ‘invoice_file.txt’ /* Name the input file */
接下来的 do while 循环逐行处理输入文件中的输入行。它使用内置的 lines 函数来判断在输入文件中是否还有未读到的行。如果没有剩下要读的行,则 lines 函数返回 0:
do while lines(input) > 0 /* Do while there are lines to read */
在 Rexx 中,所有内置函数都很容易识别,因为这些函数后面都会紧跟着括号,括号中包含函数的输入参数。函数与紧随的左括号之间不能有空格。前面的语句表明,lines 函数只带有一个参数,该参数就是它将测试其 "end of file" 的文件的名称。记住,在我们的脚本中,变量 input 指的是名为 invoice_file.txt 的输入文件。
现在便到了程序的核心。这一行使用 Rexx 的 pos 内置函数来判断输入行是否包含字符串 INVOICE OVERDUE:
if pos("INVOICE OVERDUE", input_line) > 0 then
pos 函数返回 INVOICE OVERDUE 在给定行中出现的位置。或者,如果在行中没有找到该短语,则返回 0。
这条语句中的测试让该脚本写一行文本到显示屏幕上,表明字符串 INVOICE OVERDUE 是否存在于输入行中。然后,Rexx 的 say 指令写输出行。在我们的例子中,say 指令有两个操作对象。第一个操作对象是用引号括起来的一个字符串文字,第二个操作对象是包含文件中当前行的变量。say 指令可以带任意个操作对象,它会自动将这些操作对象连接在一起,并将它们发送到用户的显示屏幕:
if pos("INVOICE OVERDUE", input_line) > 0 then
say "Found it! Here’s where:" input_line
else
say "Not found in this line:" input_line
好了。您已经看到了一个完整的 Rexx 脚本。从中可以看出,Rexx 在语法方面要求很少,而且没有“专用字符”。这是不是使之成为容易的语言的原因呢?
Rexx 为什么容易
我给出的简单脚本演示了 Rexx 的易用性。例如,它表明您不需要声明或预定义程序变量。您可以在任何时候、任何地方直接引用一个新的变量,Rexx 会定义这个变量。例如,程序中的第一行通过给变量 input 赋一个值自动定义该变量。在使用这个变量之前,不需要声明或预定义该变量。
同样也不需要声明变量的数据类型。在 Rexx 中,所有变量都是无类型的。而且,变量包含可变长度的字符串,变量的内容便定义了变量的类型。如果您将一个看上去像是数值的字符串赋给一个变量,那么 Rexx 将允许您在此变量上执行计算。如果将一个字符串赋给一个变量,那么 Rexx 将允许您在此变量上执行字符串操作(例如解析、模式匹配或并置)。有些语言要求预定义变量,并指定变量的“数据类型”,而 Rexx 则通过变量的内容和使用情况动态地定义变量。必要时,Rexx 透明地转换数据,并且将很多细节工作自动化,这一点把使用其他语言的程序员吸引了过来。
下面是一个简单的例子:
a = 3 /* Create a numeric variable */
b = "4" /* This string value also represents a number */
say a + b /* Displays the numeric result: 7 */
say a || b /* Concatenate the two strings together… */
/* Displays: 34 */
c = "Hi!" /* Create variable that is a character string */
say a + c /* This results in error! You can not */
/* add a character value to a number */
-> SYNTAX: Bad arithmetic conversion (error 41)
该代码首先创建两个变量,这两个变量包含表示数的值。(在 Rexx 中,数 是由数字组成的任何串,中间可以包含小数点,前面还可以有符号。数还可以用科学或工程计数法中的指数形式表达。)第三条语句展示了两个数的相加,第四条语句表明这两个变量还可以看作是由单个数字组成的字符串。第四条语句通过并置操作符 || 将两个字符串(恰好是由数字组成的字符串)并置或粘贴在一起。最后两行表明,虽然 Rexx 可以随时自动执行转换,但它不允许将非数字字符串与一个数相加。在计算中,只有包含数值的变量才可以看作数。
让我们回到最初的那个例子:扫描字符串 INVOICE OVERDUE 的脚本。注意,该脚本不打开它的输入文件。文件很像是变量,在使用之前无需显式地定义它们 — 您可以直接开始读或写文件。同样,程序在使用文件之后不必关闭文件,因为当程序终止时文件会自动关闭。我也没有正式地结束该脚本(您可以编写一个 Rexx 出口指令来结束 Rexx 代码,但这不是必需的)。
Rexx 除了为您执行这些隐式操作之外,Rexx 还很容易,因为它是一种格式自由的语言。您可以随意使用空格、空白行和缩进。作为一个简单的例子,您也可以像下面这样来编写 if 语句,而结果是一样的:
if pos("INVOICE OVERDUE", input_line) > 0
then say "Found it! Here’s where:" input_line
else say "Not found in this line:" input_line
就格式而言,Rexx 是编程语言中最为宽松的。而且,它不是大小写敏感的。它的指令、函数和变量可以用大写、小写或大小写混合的形式编写。例如,您也可以将变量名 input_line 写为 INPUT_LINE、Input_Line 或 Input_line;对于 Rexx 来说这都是一样的。还有一种编写 if 语句的方法,即使用大小写将 Rexx 指令和函数与语句的其他部分区分开来:
IF POS("INVOICE OVERDUE", Input_Line) > 0 THEN SAY "Found it! Here’s where:" Input_Line ELSE SAY "Not found in this line:" Input_Line
Rexx 为什么强大
除了它的易用性外,Rexx 的基本设计使得它成为一种强大的语言。如 图 1 所示,Rexx 有大约 20 条指令作为一个小小的核心。这个核心周围有大约 70 个内置函数。这样一来,基础的东西很容易学习,然后又可以逐渐增长函数方面的知识。这同时也意味着 Rexx 的强大性。除了内置函数外,Rexx 脚本很容易访问免费的外部函数库、工具和接口。这涉及每种能想像到的接口,包括数据库访问、图形用户界面、XML、Web 服务器编程、图、 MIDI 接口、Windows Registry 更新、语音合成以及 Apache 编程 — 只要您提供名称,Rexx 就能访问。
图 1. Rexx 的组成
Rexx 之所以强大,很大程度上是因为它是一种“胶水”语言。Rexx 脚本容易发出操作系统命令。因此,数年前 IBM 就选择 Rexx 作为用于其大型主机和其他操作系统的“命令过程语言”。Rexx 将现有的代码粘合在一起 — 不管代码的形式是操作系统命令、界面 API、服务、小配件、对象、函数、接口还是工具 — 并利用这一点获得更大的生产率。这就是 Rexx 之类的脚本语言比传统的、需要编译的编程语言(如 C++、C、COBOL 或 Java™)要强大得多的原因。虽然这些语言通过一定的努力也可以发出操作系统命令以及使用一般的接口,但 Rexx 之类的脚本语言是专门为此而设计的。
Rexx 最强大的特性之一是数组(在其他编程语言中有时候也称为表)的实现。使数组强大的原因是,数组不但可以通过数字下标索引,而且还可以用字符串作为数组的下标。因此,数组支持所谓的按内容寻址的存储器或关联存储器。这使得 Rexx 数组的威力远远超出了编程语言中表的威力,后者只支持数字下标。例如,数组可以支持字典查询,并为高级类型的数据结构,例如键-值对、链接表、双链表和树形成基础。数组是将变量与值以对程序最有意义的任何方式相关联的常用手段,所以更应该将它们称作复合变量。
Rexx 特性
接下来,我将简要地描述 Rexx 的一些其他特性。该语言包括一组完整的指令,用于控制程序逻辑(例如 do、do while、if、if-then-else、select、call、return 和 exit)。它支持结构化程序设计 和模块性,这是作为广为接受的程序设计最佳实践的原则。但是 Rexx 是一种强大的语言,包括用于非结构化逻辑的指令,在少数情况下需要用到这些指令。这些指令包括 iterate、leave、do until、do forever 和 signal (大致类似于其他语言中的 goto)。
我曾提到,Rexx 包含 70 多个内置函数。这些函数分为字符串操作、位操作、数字、输入/输出、转换、环境和杂项等类别。Rexx 脚本像调用内置函数或用户编写的函数一样调用外部函数(假设已建立到外部函数库的连接)。所以,当使用外部函数库或附加函数库时,Rexx 代码像对待该语言的内置特性一样引用那些函数。
与大多数解释器一样,Rexx 支持交互式调试。您可以运行一个脚本,在任何时候停止它,检查脚本的变量,甚至重新运行代码或者修改代码。Rexx 内置的调试器使得发现和修复逻辑错误非常容易。交互式调试通常被认为比批模式调试更好(Rexx 也支持批模式调试)。
Rexx 还包括一个异常或错误处理程序。这可以为很多常见的错误条件(例如语法错误或算术上溢)设陷,并将控制流转移到您自己编写的一个专门的错误处理例程。异常设陷提供了通过一个单独的例程来管理常见错误的标准方式。
Rexx 还支持一种名为外部数据队列(external data queue) 的通信机制,但是通常被简单地称为栈。作为 Rexx 独有的一个强大特性,栈为 Rexx 例程或程序之间的通信提供了手段。取决于主机操作系统和 Rexx 解释器,栈支持相同机器上不同程序甚至不同机器上的不同程序之间的通信。这包括跨 Internet 的远程通信。当然,Rexx 脚本还可以采用更传统的通信手段,例如 TCP/IP、FTP、套接字和管道。
最后,我应该提到 Rexx 脚本的可移植性。Rexx 有一个较强的语言标准,本文提到的所有解释器都遵从这个标准。这不仅使 Rexx 技巧可以转移,而且表明这种脚本是可移植的。有了标准 Rexx 脚本,您可以很容易地将它在 Linux、Windows、大型主机、手持设备之间移植。如果脚本发出特定于操作系统的命令,那么 Rexx 会提供一些免费的、跨平台接口来缓冲脚本对平台的依赖。
下载免费的 Rexx
我曾提到,Rexx 是和所有 IBM 操作系统捆绑在一起的。此外,您可以下载免费的或开放源码的用于任何操作系统的 Rexx。一共有 8 种免费或开放源码 Rexx 解释器。每种解释器都符合 Rexx 标准,所以您的 Rexx 技巧适用于所有这些解释器,并且 Rexx 脚本在上述任意解释器下均可运行。这些解释器之间的不同之处在于它们所支持的平台以及所提供的额外的东西。例如,有些解释器在手持设备上运行,其他一些解释器提供了特定于操作系统的语言扩展,其他解释器支持完全面向对象的编程。
下面是 6 个免费的 Rexx 解释器的概述:
解释器 | 平台 | 简介 |
Regina | 所有主流操作系统 | 最流行的 Rexx 解释器。它拥有很大的用户社区,这意味着可以获得广泛的支持,而且它完全使用免费的工具和接口。它附带了很多额外的内置函数以及非常好的、专业的文档。如果您刚接触 Rexx,那么我建议从 Regina 开始。 |
Rexx/imc | Linux、UNIX、BSD | 这是面向 UNIX 和 Linux 的解释器,包括用于这两种环境的扩展。它长期提供良好的支持。 |
BRexx | Linux、UNIX、Windows CE、Mac OS、16 位和 32 位 DOS 及其他 | 这种非常快的解释器占用内存很少,可以在很多平台上运行,包括资源受限的系统,例如 Windows CE、嵌入式 Linux 和 DOS。它提供了很多额外的函数及接口,并长期提供良好的支持。 |
Reginald | Windows | Reginald 为 Windows 程序员定制和扩展 Rexx。它易于使用,并且包括很多 Windows 工具,例如一个 GUI、语音、MIDI 和媒体函数。Reginald 为诸如 VBScript 之类的专用工具提供了一种标准的语言方案,并提供了包含示例在内的良好文档。 |
r4 | Windows | r4 扩展了用于 Windows 的 Rexx,提供了很多工具,包括一个 GUI 窗体工具、彩色的文本文件浏览器和编辑器、超过 135 种 Windows 命令工具、XML 到 HTML 的自动转换器、GUI 小配件,等等。它还包括很好的教程以及示例脚本。 |
用于 Palm OS 的 Rexx | Palm OS | 这种解释器通过脚本将 Palm OS 应用程序与数据库粘合在一起,脚本无需离开当前的应用程序便可运行。这些脚本可以访问所有的 Palm 数据和资源,包括 TCP/IP、红外线、USB 和串行通信、控制台、剪切板等。它在本地运行,带有易于遵循的教程,其中包含很好的示例脚本。 |
除了这些标准的过程 Rexx 解释器以外,还有两种面向对象的 Rexx 解释器。它们是完全面向对象的语言,带有完整而强大的类库。它们支持所有 OOP 原理,包括类继承、继承、多重继承、封装、抽象和多态。这两种产品都是标准的过程 Rexx 的超集,所以通过使用标准 Rexx 特性和函数便可以立即开始用它们来编程,然后逐渐涉及面向对象特性。此外,标准的 Rexx 脚本可以不作修改地在这两种解释器下运行:
解释器 | 平台 | 简介 |
Open Object Rexx | Windows、Linux、UNIX | 这是传统 Rexx 的完全面向对象的超集。它由 IBM 开发,在 2004 年末成为开放源码的。现在它由 Rexx Language Association 升级和维护,是最广泛使用的面向对象 Rexx 解释器。 |
roo! | Windows | roo! 也是传统 Rexx 的完全面向对象的超集。它与标准 r4 Rexx 解释器来自相同的公司,附带了同样丰富的 Windows 工具。它还包括简洁易懂的教程,帮助理解标准 Rexx 编程与面向对象 Rexx 编程之间的差异。 |
最后要提到的是,还有一种用于 Java 环境的 Rexx,即 NetRexx。在本文中讨论的所有 Rexx 解释器当中,只有这种解释器不符合 Rexx 语言标准 — 所以称其为“类 Rexx”最为恰当。这种解释器的作用是将 Rexx 的易用性带入到 Java 环境。NetRexx 脚本使用 Java 类,它们可以通过 Java 脚本创建 Java 类。NetRexx 允许编写 applet、应用程序和 servlet,而不会与 Java 中继承于 C 的语法发生冲突。您甚至可以使用它来创建 Java Beans 和生成带有完整注释的 Java 代码。NetRexx 同时支持客户端和服务器端脚本,可以在任何 Java 虚拟机(JVM)上运行。
接下来的内容
在我接下来的文章中,我将更多地涉及 Rexx 编程的技术方面,并提供一些实用的编程示例。这些示例脚本将演示如何使用 Rexx 作为快速开发访问 DB2 UDB 数据的程序的工具。除了传授更多关于 Rexx 脚本编制的知识外,还将提供相应的实用数据库示例。我将采用 Regina Rexx 解释器,它为示例脚本访问 Windows 服务器上的 DB2 UDB。但是我要使用的 Rexx 和数据库接口都可以在 Linux、UNIX 和其他操作系统之间移植。
使用像 Rexx 这样的开放源码语言的一大好处是,可以随处找到很多免费的相关参考资料(参阅 参考资料)。
开放源码/免费软件运动是我们这个时代伟大的技术传奇之一。当今另一个大趋势就是脚本编制。Rexx 立足于这两大趋势的交叉点。它提供了一种免费的、易于使用的、强大的、标准化的通用脚本语言。有了它,就可以快速地为各种不同问题编写程序,并且成本很低。尽情编写脚本吧!
更多精彩
赞助商链接