介绍Rebol
Rebol 的描述 |
如何描述 Rebol 语言?革命性的,功能强大的,灵活的 -- 而且是不同的。事实上,Rebol 可能不象您以前用的任何一种语言。在用一种直接的同时也是“非常规”的方式来设计解决实际编程任务方面,Rebol 为那些想在脚本语言中寻求更多的编程者提供了一个崭新的编程工具箱。
对于我们开发者而言,学习 Rebol 可以给予我们新的活力和富有挑战性。在承诺有些完全不同的同时,Rebol 还使用了新的编程模式,在与大多数传统语言使用的有些相似的同时,又是“如此不同”以至于经验丰富的开发者都感到困惑。
Rebol 特性 |
在许多方面 Rebol 是与众不同的。它使用自然的类英语语法,且支持许多数据类型,象 URL 和电子邮件地址。Rebol 是一种支持因特网的语言;使用 Rebol, 可以用一行简单的代码实现下载 Web 页面或者发送一条电子邮件消息。不但如此,Rebol 还提供称之为“dialecting”的高级功能,此功能允许您创建用于您自己特殊目的的子语言,特别为您使用 Rebol 的任务定制。
然而,在您接触这些招人喜爱的特性之前,掌握 Rebol 的基础知识是很重要的。这就是在本教程中我们将要做的。在您熟练掌握这些基础知识后,我将给您展示一些在线资源,使您了解 Rebol 的更先进特性。
安装 |
下载 Rebol/Core |
进入 http://www.rebol.com 后,选择开发者部分,然后单击“Downloads”。选择可用于您平台上的 Rebol/Core 的最新版本。目前,有以下一些版本可用:libc5、libc6 x86 Linux、Linux/Alpha、Linux/PPC、Linux/Sparc、UltraSparc、Linux/StrongARM、 MIPS 和 68K! 很显然,在 Rebol 的移植方面 ,其开发者花了很大的心血。
对于 libc6 x86 Linux,Rebol/Core 档案标志为“core042.tar.gz”。在下载完您所需的文档后,创建一个“rebol”目录,并将此文档放至该目录下。进入该目录,输入
$ tar xzvf core042.tar.gz
将此文档解包。五个文件将解包到当前目录,这其中包括 rebol 可执行文件。
启动 Rebol |
启动 Rebol。您将看到类似于以下情况:
配置 Rebol |
在这里,您将要配置系统中网络方面的选项,包括输入您的电子邮件地址、SMTP 和 POP 服务器以及网络代理的设置。由于 Rebol 是支持因特网的语言,它需要这些设置选项以访问因特网。
(这里新的版本(2.6.2)已经不需要了,只有执行do setup.r才会进入配置过程)
在你完成配置步骤后,Rebol 会询问在当前目录是否允许创建“user.r”文件。您的设置将存储在这个文件中。继续,并说 "Y"。这是 Rebol 的内置安全性支持的一个例子。
下次启动 Rebol 时,记住要从“rebol”所在目录启动。这样的话,Rebol 将会找到 user.r 文件,并且自动装入网络设置。
第一个提示符 |
在完成配置后,您处在交互式 Rebol 解释器内部。Rebol 提示符类似于:
>>
继续,输入“help”并敲入 Enter 键来查看 Rebol 的内置帮助页。“help”命令也能接受变量。尝试输入“helpprint ”。您将在屏幕上看到 print 函数的摘要。
Rebol -- what? |
>>what
"what" 命令显示了一个所有全局定义的函数列表。
退出 Rebol |
>> quit
....您将返回到 shell 提示符。既然知道了如何进入和退出解释器,现在该是熟悉语言本身了。
第三章 Rebol-语言
介绍数据类型 |
Rebol 的出色之一是它有大量内置的数据类型,这些已设计成反映您在现实世界中发现的数值,如电子邮件地址、URL、日期、时间和货币值。让我们开始熟悉它们。
在 Rebol 提示符下,输入:
>> [email protected]
== [email protected]
这个电子邮件地址送给解释器后,Rebol 仅把它的重复返还回来。这是 Rebol 的标准处理方式 -- 当文字值输入给解释器时,它将该值重复返回。现在您也许想知道 [email protected] 是什么类型的值。大多数语言将电子邮件地址作为字符串处理,所以也可能猜想 Rebol 亦是如此。然而,您会惊奇地发现 Rebol 所作的比这更有用。
探索数据类型 |
为了看 [email protected] 是什么数据类型,输入:
>> type? [email protected]
== email!
字 type? 是接受变量的函数,它返回变量的数据类型。正如您所见,Rebol 事实上认识 [email protected] 是一个电子邮件地址 -- 很不可思议!我们不需要特殊的语法去指定电子邮件地址;Rebol 可以将该值识别成电子邮件地址,因为它注意到嵌入的"@"字符。
让我们继续。输入
>> type? $5.00
== money!
同样,Rebol 认识 $5.00 表示货币值。
您可能想知道为什么在 email!和 mony!后面有惊叹号。答案很简单 -- 所有数据类型名称以一个惊叹号结尾。除此之外,查询属性的函数以问号标记结尾(如 type? 函数)。Rebol 通过构造类似于传统书写语言(如 English)的语法,来使其更具用户友好性。
许多数据类型 |
试着输入以下 Rebol 表达式,来看 Rebol 所识别的数据类型的每个值:
>> type? 1
>> type? 1.0
>> type? "foo"
>> type?{foo}
>> type? http://www.gentoo.org
>> type? true
>>type? yes
>> type? :print
>> type? money!
第四章 Rebol字
介绍字 |
如 C 语言的变量能代表数据一样,Rebol 有它自己的变量,称之为字。这里有一个如何将字与数值联系在一起的示例。
>> myval: $5.00
注意冒号后边要有空格。
在这个示例中,myval 一直与值 $5.00 相关联。在表达式中用 myval 会立即求出值:>> myval
== $5.00
>> myval + 1
== $6.00
在 Rebol 中,将字与值联系起来是很普遍的,创建一个字/值对。字也是不区分大小写的,所以输入 myval 与 MyVal 是一样的
没有值的字 |
现在尝试输入任何旧字到解释器。会出现如下错误信息:
>> foo
** Script Error: foo has no value.
** Where: foo
缺省情况下,Rebol 会自动对所有字求值。通过"求值"Rebol 将自动用字所关联的值来替换字。如果字没有与值关联,那么 Rebol 返回错误。
定义新字 |
基于现有字的值,我们也可以定义新的字。尝试这个示例:
>> myval: $5.00
== $5.00
>> myval2: myval + 1
== $6.00
>>myval2
== $6.00
>> myval
== $5.00
>> myval: myval + 1
==$6.00
>> myval2
== $6.00
这里,我们基于 myval 定义 myval2。然后,增加 myval 的值,并打印 myval2 的值,发现 myval2 的值没有更改。
Rebol 的描述 |
正如您所见,Rebol 字充当了如 C 和 C++ 语言中变量的功能。您可能甚至想知道为什么 Rebol 的开发者称 Rebol 的变量为字,而不是遵循标准的术语。问得好!这正是本教程下面要讲的,我将演示 Rebol 字与标准 C 变量所不同的独一无二的特征。
字的基本知识 -- 总结 |
当 Rebol 解释器遇到字,它正常的反应是将它求值。当字被求值时,它被其关联的值所替换。所以,譬如,如果字 myemail 与值 [email protected] 相关联,那么在 Rebol 解释器提示符下输入:
>> myemail
....将使解释器返回:
== [email protected]
这是 myemail 的值。这表明,根据 Rebol,字 maemail 有含意,它代表了 [email protected] 这个电子邮件地址。这会很明显,Rebol 让您用字能作一些不寻常的事,呆一会儿我们会看到。
数学运算符 |
当我们在几屏前使用美圆金额时,用标准的算术运算符 +。当然,Rebol 支持整套算术运算符,包括标准的 +、 -、 *、和 /。除此之外,它还包含 // 余数运算符。
当您在 Rebol 中写数学表达式时,您需要知道两件重要事情。首先,在值与运算符之间要放空格;解释器不能正确分析 1+7 ,而 1 + 7 可以。其次,Rebol 从左到右对算术表达式求值。它没有象 C 中特殊的运算符优先权。如果您想显式的表明算术求值的顺序,可以用括号将表达式括起。(这一点要注意哦)
前缀运算符 |
除了标准的"中缀"(在当中)算术运算符,Rebol 也有内置的算术运算符。以下是它们的工作原理:
>> abs -23
== 23
>>add 23509 230
== 23739
>>divid 4 2
== 2
>>multiply 30 30
== 900
>>remainder 9 4
== 1
>>subtract 4 9
== -5
日期 |
Rebol 对日期也有极好的内置支持。要获取当前日期,用字"now":
>> print now
30-Sep-2000/22:41:19-6:00
通过在日期上加上或减去一个整数,可以偏移该日期一定天数。譬如,可以表示两周前的日期:
>> print now + 14
14-Oct-2000/22:43:13-6:00
用now: 3可以把now变成3,如果要恢复过来就不知道怎么做了,不过幸好我前边用timenow: now + 3,然后又用 now: timenow - 3 恢复过来了,好险啊,吼吼
许许多多数据类型 |
Rebol 有相当多的数据类型;我们这里没有篇幅来涵盖所有数据类型;这里有一个数据类型的部分列表:整数、小数、时间、日期、货币、逻辑、字符、空值、字符串、二进制、电子邮件、文件、url、issue、元组、标记、块、散列、列表、路径和字。
许多数据类型都有它自己特殊的运算符和函数,且数据类型可以以无数种方式进行交互。譬如,您可以从数据中抽取时间;附加到字符串;打开、关闭和写入文件。在 Rebol 用户手册(更详细信息请参阅 参考资料)详细描述了有关所有这些数据类型和它们相关联的运算符和函数.
第五章 字和表达式
Rebol 的描述 |
以前,当对 myemail 求值时,Rebol 解释器将"==[email protected]"写到屏幕上。当交互使用解释器时,Rebol 打印任何已求值的表达式。然而,当 Rebol 代码从文件执行时(不用解释器,而作为一个 shell 脚本),将不能看到上面的输出。在这种情形下,应该用 print 命令生成输出。也可以交互使用打印:
>> print myemail
[email protected]
Rebol 显示了 myemail 的值,但不打印"==[email protected]"。这是因为 print 将 email 的值输出到屏幕,而不是返回值本身。
探测 |
>> print myemail
[email protected]
>> type? myemail
==email!
这里有一些诀窍,Rebol 提供了一种更清晰的方式来立即执行这两个步骤...
简单地输入:
>> type? probe myemail
[email protected]
== email!
probe 字期望单个字或块(后面将讲述)作为变量。它将打印该字的值,并返回该字的值。在这个示例中,type? word 随后对该值求值,显示 [email protected] 值的类型。可以认为 probe 是标准 UNIX "tee"命令的 Rebol 版。
文字字 |
大多数时间,当我们引用 Rebol 的字时,Rebol 能做我们想做的 -- 对字求值,将值传给函数或在交互式解释器上显示该值。然而,有时这并没有精确到我们想要做的。有时当我们想引用字本身,而不是它所关联的字。对于这种情形,Rebol 提供了一个方便的文字字语法。看一下这个示例:
>> type? myemail
== email!
>> type? 'myemail (只要是以单引号开头的,Rebol都认为是字(word))
== word!
朗读它 |
为了帮助您掌握文字的字的概念,您要大声地说(用嘴,用 English 或您熟悉的语言!)代码所正在做的。是的,这意味着您盯着监视器时要自言自语。不要害怕 -- 如果您对这种事情感到很困窘,那您就假装是 Jean Luc Picard (USS Enterprise 的 Captain),您正在大声对计算机发命令。
这个练习的关键是,当您看到象这样写的字:
foo
....您应该说"foo"。
当您看到象这样写的字:
'foo
....您应该说"the word foo"。
第一条命令
这里有一个您已经输入到 Rebol 解释器的命令:
>> myemail: [email protected]
如果您是 Jean Luc Picard,您也不会使用和计算机键盘一样过时的东西来输入这个命令。事实上,您会大声地说(提示):
"Computer,associate the word myemail with the value[email protected]."
第二条命令 |
作为 Jean Luc Picard,不要用键盘输入这些怪异的东西,小心会得腕骨综合症:
>> myword: 'myemail
....您要从专门设计的 Captain 椅起来,发号施令:
"Associate the word myword with the word myemail"
注意到不同吗?有点微妙差异但很重要。前缀 ' 意味着您正在谈论 the word。没有 ',意味着正在谈论字的值。
手工求字值 |
现在,有一个叫 myword 的字,它有个值是它本身(也是字)。好,这很有意思,您如何告诉 Rebol 去求该字的值?很容易:
>> do myword
== [email protected]
棒极了!现在,当 Rebol 求字值时,我们能够精确地控制它了。
无事空忙 |
十分感谢 do 函数,我们也可以输入:
>> do 'myemail
== [email protected]
然而,这没有什么意义,因为仅输入字本身也能实现同样的结果:
>> myemail
== [email protected]
字关联 |
字与值相关联有另一种方法。除了输入:
>> myvar: $5.00
也可以输入:
>> set 'myvar $5.00 (这里有引号)
这两种表达式的效果是相同的。大声朗读它们 "set the word myvar to the value $5.00"。set 字展开了许多强大的可能性。
考虑:
>> myword: 'cost
== cost
>> set myword $5.00
== $5.00
最后的表达式事实上不影响字 myword 的值;它将 cost 与值 $5.00 关联。(如果不相信我,那就输入 "print cost"。)您可以大声地朗读最后一行 "set the value of myword to $5.00" 或 "set the word cost to $5.00"。由于 myword 的值是字 cost,这两个句子表示同样的事。
取消设置 |
字可以设置,也可以取消设置:
>> unset 'cost
这将取消与字 cost ('cost) 关联的值。如果在该命令之后,立即输入 "print cost",会返回错误,因为 cost 没有值。有兴趣的话,尝试输入 "print cost"。
即使字 cost 不再有任何值,下面的代码不会产生错误:
>> print 'cost
cost
这是因为执行了命令 "print the word cost"。print 函数首先打印字的名称,而不是它的值。' 字符防止 cost 被求值。
帮助 Rebol 解决 |
>> myemail: drobbins
不幸的是,这不起作用。解释器没有办法知道 "drobbins" 是什么。Rebol 没有找到嵌入在字符串中的 "@",所以它认为 drobbins 是一个常规字,并对它求值。不幸的是,字 drobbins 没有与它相关联的值,因此出现这种错误。
** Script Error: drobbins has no value.
** Where: myemail: drobbins
幸运的是,有这样一种变通方法。不是输入:
>> myemail: drobbins
....而是输入:
>> myemail: make email! "drobbins"
没有错误,如果查询 myemail 的类型,我们会看到所期望的结果:
>> type? myemail
== email!
make 函数允许我们创建特定类型的值。我们指定类型,而不是依靠 Rebol 去试图检测我们的数据类型。
使它起作用 |
>> mymoney: make money! "drobbins"
** Script Error: Invalid
argument: drobbins.
** Where: mymoney: make money! "drobbins
第六章 块
构建块 |
现在来看一下称之为块的 Rebol 构造。在 Rebol 中,可以用块来组织数据的集合。用 [ 和 ] 将一组值括起来创建块。
>> myblock: [ this and that ]
== [this and that]
块的灵巧之一是它们能包含数据和代码。它们能包含不关联值的字,并且块的内容是不立即求值的。譬如,Rebol 接受 myblock 的定义,即使字 this and that 没有值。
代码块 |
可以在块中插入代码,如下:
>> mycode: [ print "foo" ]
== [print "foo"]
用方便的 do 函数来执行该代码:
>> do mycode
foo
块特性 |
这里有一个当执行时实际上不做任何事情的代码块,但它演示了 Rebol 的特性:
>> mydata: [ 1 2 3 ]
== [1 2 3]
这看上去象数据块,但我们也能把它当作代码来执行。作为代码,这个块包含了三个独立的表达式,1、2 和 3。每个表达式都各自返回 1、2 和 3 的值。现在让我们来执行这个块。
>> do mydata
== 3
正如您所见,Rebol 返回在代码中遇到的最后一个值。然而,整个代码块是按照顺序来执行的,不是仅指最后的元素。
嵌套块 |
块可以嵌套:
>> instructions: [
[ [ remove hard drive from chassis ]
[ [ throw hard drive out window ]
[ [ scream "foo foo foo!" ]
[ ]
从第二行开始到第五行的 [ 字符实际上是 Rebol 提示符。这是 Rebol 提醒我们正在进入多行块的方式。尝试将该块输入解释器,您就能看到我所说的。
执行结果是:== [scream "foo"]
访问块 |
我们可以访问块中的元素:
>> myblock: [ jimmy cracked corn ]
== [jimmy cracked corn]
>> first myblock
== jimmy
>> myblock/1
== jimmy
>> last myblock
== corn
>> myblock/3
== corn
>> myblock/2
== cracked
块路径 |
>> order: [
[ amount 10
[ cost $3.50
[ email
[email protected]
[ ]
== [
amount 10
cost $3.50
email [email protected]
]
>> order/email
== [email protected]
>> order/cost
== $3.50
注意到 order 块包含六个独立的字,字 amount 不与任何值关联(我们没有输入 "amount:10",而是输入 "amount 10",这是两个毫不相关的字)。"order/cost" 称为路径.
第七章 参考资料
获取用户指南 |
管在本教程中我们已经讲了许多,但我们仅触及了 Rebol 编程语言的表面。为了进一步深入下去,推荐您下载 Rebol 用户指南。它编写得很好,很透彻。现在您已经了解了 Rebol 的基本知识,也就不难理解这本书。为了让 Rebol 自动下载用户指南,输入:
>> do do http://www.rebol.com/users-guide.r
Rebol 将问您是否在磁盘上创建该文件。仅需点击 A(代表“所有”),“Rebol 用户指南”将自动地下载到您目前的工作目录下!很简便,不是吗?(这个被证实已经找不到users-guide.r了)
其它参考资料 |
希望您喜欢这篇文章,您还要丰富您的 Rebol 知识!