【程序设计】6.3 [重复用] 可复用脚本
6.3 可复用脚本
学到现在,我们都在一个网格里写代码。 这个网格可以被保存成一个扩展名为.splx 的文件,我们称它为一个脚本。
现在我们学会了写自定义函数被重复调用,但是这个函数只能在一个脚本中使用,新建一个脚本后还得再重抄一遍,它并不像库函数那样可以在任何一个脚本中使用。
怎么才能做到库函数的这个效果呢?
SPL 提供了能在某个脚本中调用另一个脚本的功能,我们以前面那个计算异常点的代码为例来说明如何做到这一点。
首先,创建一个新脚本,再使用程序菜单下的参数功能,会跳出这么一个对话框:
先要在这里填写这段要被调用脚本的参数。假定这个脚本会接收一批点的坐标作为参数,计算出异常点的序列并返回。我们设计有三个参数:X 是一个序列,存储横坐标;Y 是一个和 X 长度相同的序列,存储纵坐标;ratio 是一个比例,表示取出距离最大的前多少比例的点(的序号)作为异常点返回。
填好的对话框会是这样:
值那一列是指缺省值,调用这个脚本时可以不写参数,就会用这个缺省值,这里随便写几个就行。
现在在网格中编写代码:
A |
B |
C |
D |
|
1 |
=X.(Y.sum( func(A3,X(X.#),X(#),Y(X.#),Y(#)))) |
|||
2 |
return A1.psort@z().to(int(X.len()*ratio)) |
|||
3 |
func |
|||
4 |
return sqrt((A3-B3)*(A3-B3)+(C3-D3)*(C3-D3)) |
脚本也是用 return 语句来返回结果。在脚本中可以直接使用参数作为变量名,事实上,如果执行一下它,也能在右下的变量表中看到参数。对于 SPL 来说,脚本的参数和有名字的变量是一回事。
A1 格利用了参数的变量名为多层循环函数确定 #的所属层次。
保存这个脚本并起个名字,比如叫 outlier.splx。现在再新一个脚本,就可调用刚才写过的脚本了。
A |
|
1 |
100 |
2 |
>rand@s(0) |
3 |
=call("outlier.splx", A1.(rand()),A1.(rand()),0.1) |
4 |
>rand@s(0) |
5 |
=call("outlier.splx", A1.(rand()),A1.(rand())) |
使用 call 函数就可以调用另一个脚本了,也能取得返回值。
需要注意的是,这个新建脚本要保存一下,且和 outlier .splx 存放在同一个路径下,SPL 一般会在当前脚本所在路径下寻找被调用脚本,还没有保存的脚本就没有所在路径,而路径不对很可能找不到。
前面编写 outlier.spxx 时有了缺省值,所以 A5 少写一个参数也可以,并且由于用了 rand@s 之后,A3 和 A5 会返回同样的结果。
如果这段脚本还是报找不到 outlier.splx 的错误,那有可能是寻址路径或主路径写的不对。使用工具菜单下的选项功能,打开对话框后切换到环境页,其中的寻址路径可能被填上不合适的内容了,被调用的脚本会优先在这个路径下寻找。
这样的好处在于,可以写一些通用脚本放在这个路径下,那么无论存在哪个路径的脚本都可以调用这些通用脚本了,不必把被调用脚本复制到调用脚本的路径下。
如果寻址路径是空时仍然找不到,那有可能是下主路径有错。对于使用相对路径的文件名(包括脚本名),集算器会首先到主路径下寻找。主路径填空时才会到当前脚本所在路径去寻找。这个规则有些复杂,是为了开发有很多脚本的复杂应用而设置的。
SPL 还提供了一个 register 函数,可以把某个脚本登记成常规函数的样子。
A |
|
1 |
>register("outlier","outlier.splx") |
2 |
100 |
3 |
=outlier(A2.(rand()),A2.(rand()),0.1) |
把自写脚本登记为函数时,最好用绝对路径或把脚本放到寻址路径中,不然很可能因为调用脚本的路径不同而找不到。登记过的函数对所有脚本都有效,并不是只对当前脚本管用,重复登记会替换掉原来的。
我们可以用一个脚本把其它常用来被调用的脚本登记成自有函数,以后每次启动集算器后执行一下这个用于登记其它脚本的脚本,就相当于增加了许多库函数。
前三章的内容,再加上这一章,就构成了现代程序语言的绝大部分流程控制的机制(面向对象语言还有重载机制,但内容较深,本书不涉及)。用于控制程序流程走向的方式也就这些了,各种不同程序语言除了用的保留字可能不同外,并没有太大的差别。学习一门新的程序语言时,这些流程控制语句连同数据类型都是基本内容。
之后,重点学习内容将转向更丰富的数据类型以及相应的函数,比如像我们之前已经接触过的序列。不同程序语言有不同的用途,在数据类型和函数方面也就有不同的侧重点,不同的程序语言,在流程控制能力上差别很小,而数据类型和函数的差异则可能非常巨大。可以说,数据类型及上的相关运算(函数也是运算)构成了程序语言的根本面貌。