要在宏中定义自己的函数,可使用 FUNCTION 块或 MACRO_FUNCTION 块:
语法:使用以下语法来定义函数:
FUNCTION 块:
%FUNCTION(type) function-name([usage] [datatype] parameter, ...) [RETURNS(return-var)] {
executable-statements
[report-block]
...
[report-block]
[message-block]
%}
MACRO_ FUNCTION 块:
%MACRO_FUNCTION function-name([usage] parameter, ...) [RETURNS(return-var)] {
executable-statements
report-block
...
report-block
%}
其中:
可以用同一个名称定义多个 FUNCTION 或 MACRO_FUNCTION 块, 这样它们就可以被同时处理。每个 块都必须具有相同的参数表。当 Net.Data 调用函数时,将以在 Net.Data 宏中定义的顺序执行具 有相同名称的所有 FUNCTION 块或有相同名称的所有 MACRO_FUNCTION 块。
对于 FUNCTION 块,在可执 行语句传送到语言环境之前,Net.Data 用变量值代替所有变量引用,执行所有函数调用并用结 果值代替函数调用。每个语言环境处理语句的方式是不同的。关于指定可执行语句或调用可执行程 序的更多信息,请参阅可执行变量。
对于 MACRO_FUNCTION 块, 可执行语句是文本和 Net.Data 宏语言结构的组合。在此情况下将不涉及语言环境, 因为 Net.Data 起语言处理器的作用并处理可执行语句。
在 Net.Data 宏调用函数之前,在其它所有块的外部定义函数。
当匹配 Net.Data 语言结构语法的字符在函数块的语言结构节中作为一部分语法上有效的嵌入程 序码(例如 REXX 或 Perl)使用时,它们可能被作为 Net.Data 语言结构而被误解释,因而导致 错误或宏中不可预测的结果。
例如,Perl 函数可能使用 COMMENT 块定界符 %{。 运行宏时,%{ 被作为 COMMENT 快的开头来 解释。然后 Net.Data 查找 COMMENT 块的结尾,当它读到函数块结尾时就认为是找到了。Net.Data 然后继续查找函数块的结尾,但当找不到时,就发出一个错误。
使用以下方式之一来使用 COMMENT 块定界符字符,或使用任何其它 Net.Data 特殊字符作为嵌 入程序代码的一部分,而不让它们被 Net.Data 作为特殊字符来解释:
例如,以下 Perl 函数包含表示一个 COMMENT 块定界符 %{ 的字符作为 Perl 语言语句的一部 分:
%FUNCTION(DTW_PERL) func() {
...
for $num_words (sort bynumber keys %{ $Rtitles{$num} }) {
&make_links($Rtitles{$num}{$num_words});
}
...
%}
要保证 Net.Data 将 %{ 字符作为 Perl 源码而不是作为 Net.Data COMMENT 块定 界符,可以用以下方式之一重写函数:
%FUNCTION(DTW_PERL) func() {
%EXEC{ func.prl %}
%}
%define percent_openbrace = "%{"
%FUNCTION(DTW_PERL) func() {
...
for $num_words (sort by number keys $(percent_openbrace) $Rtitles{$num} } {
&make_links($Rtitles{$num}{$num_words});
}
...
%}
MESSAGE 块让您根据函数调用的成功或失败来确定在函数调用之后如何继续下去,并让您为函数 的调用程序显示信息。在处理消息时,Net.Data 为每一个对 FUNCTION 块的函数调用设置 语言环境变量 RETURN_CODE。在对 MACRO_FUNCTION 块的函数调用上不设置 RETURN_CODE。
一个 MESSAGE 块由一系列消息语句组成,每个消息语句指定一个返回码值、信息正文和一个 要进行的操作。Net.Data 参考中语言结构章节中显示了 MESSAGE 块的语法。
MESSAGE 块可具有全局或局部作用域。如果 MESSAGE 块是在 FUNCTION 块中定义的,则它的 作用域局部在该 FUNCTION 块中。 如果它是在最外层指定的,则 MESSAGE 块是全局作用域,并且对于 Net.Data 宏中执行的所有函数 调用都是活动的。 如果您定义多个全局 MESSAGE 块,则最后定义的块是活动的。
Net.Data 使用这些规则来处理来自一个函数调用的 RETURN_CODE 变量的值:
下例显示 Net.Data 宏的一部分,其中具有一个全局 MESSAGE 块和一个函数的 MESSAGE 块:
%{ 全局消息块 %}
%MESSAGE {
-100 : "Return code -100 message" : exit
100 : "Return code 100 message" : continue
+default : {
This is a long message that spans more
than one line. You can use HTML tags, including
links and forms, in this message. %} : continue
%}
%{ local message block inside a FUNCTION block %}
%FUNCTION(DTW_REXX) my_function() {
%EXEC { my_command.mbr %}
%MESSAGE {
-100 : "Return code -100 message" : exit
100 : "Return code 100 message" : continue
-default : {
This is a long message that spans more
than one line. You can use HTML tags, including
links and forms, in this message. %} : exit
%}
如果 my_function() 返回 RETURN_CODE 值为 50,Net.Data 将以此 顺序处理错误:
当 Net.Data 找到一个匹配时,它向 Web 浏览器发送信息正文,并检查请求的操作。
当您指定了 continue 之后,Net.Data 继续处理 Net.Data 宏,然后才打印信息正 文。例如,一个宏调用 my_functions() 5 次并在用 MESSAGE 块处理期间发现错误 100,则程序的输出是这样的:
. . . 11 May 1997 $245.45 13 May 1997 $623.23 19 May 1997 $ 83.02 return code 100 message 22 May 1997 $ 42.67 Total: $994.37