REXX中是否有关联数组的方法?

7

我有一些Perl代码(用于性能分析),最初在Linux下开发,现在需要移植到主机。显然,在该平台上REXX是首选的脚本语言,但这个Perl脚本严重依赖于关联数组(基本上是索引为字符串的数组)。

在REXX中是否有类似的方式?如果有,我该如何编写类似的代码:

$arr{"Pax"} = "Diablo";
$arr{"Bob"} = "Dylan";
print $arr{"Pax"} . "\n";
if (defined $arr{"no"}) {
        print "Yes\n";
} else {
        print "No\n";
}

2
+1 个 REXX 问题。自从我的 OS/2 时代以来,我就没有考虑过 REXX。 - ggutenberg
2个回答

13
你可以使用词干变量,虽然不完全像数组,但非常相似。
/* REXX */
NAME = PAX
ARRAY.NAME = "DIABLO"
NAME = BOB
ARRAY.NAME = "DYLAN"
NAME = 'PAX'
SAY "ARRAY.PAX " IS ARRAY.NAME
NAME = 'BOB'
SAY "ARRAY.BOB " IS ARRAY.NAME
NAME = 'SANDY'
SAY "ARRAY.SANDY " IS ARRAY.NAME
IF ARRAY.NAME = "ARRAY.SANDY" THEN SAY "ARRAY.SANDY IS EMPTY"

上述 Rexx 会打印

ARRAY.PAX  IS DIABLO
ARRAY.BOB  IS DYLAN
ARRAY.SANDY  IS ARRAY.SANDY
ARRAY.SANDY IS EMPTY

它们也可以像a.b.c一样复合。 如果一个stem变量为空,将返回其本身。 我所知道的没有一种方法可以迭代一个不使用连续数字作为索引的stem。

IBM手册涉及Stem变量

Perl作为额外的免费功能可用于ZOS IBM Ported Tools for z/OS


11
我只是想在Deuian提供的答案上再添加一点内容。我同意,REXX干扰变量是答案。
简单的REXX变量默认为它们自己的名称。例如:
/* REXX */
SAY X

会一直打印 "X" 直到 X 被赋予其他值:

/* REXX */
X = 'A'
SAY X

将打印“ A”。

到目前为止没有什么大的惊喜。干茎变量有些不同。干茎的头部永远不会被评估,只有初始点之后的部分才会被评估。

举个例子:

/* REXX */                                                           
X. = 'empty'   /* all unassigned stem values take on this value */
A. = 'nil'
B = 'A'        /* simple variable B is assigned value A */                                                      
X = 'A'        /* simple variable X is assigned value A */                                                      
SAY X.A        /* prints: empty */                                 
X.A = 'hello'  /* Stem X. associates value of A with 'hello' */
SAY X.A        /* prints: hello */                                   
SAY X.B        /* prints: hello */                                   
SAY X.X        /* prints: hello */                                   

注意XA这些名称并没有被评估,但是它们后面出现的变量XA被评估了。有些人可能会觉得这有点混淆 - 如果你花点时间去想,它就会变得非常清晰。

Z/OS版本的REXX没有提供一种自然的方式来迭代一个stem变量。最简单的方法是构建自己的索引。例如:

/* REXX */
X. = ''
DO I = 1 TO 10
  J = RANDOM(100, 500) /* Random # 100..500 */
  X.INDEX = X.INDEX J  /* concatinate J's with 1 space between */
  X.J = 'was picked'   /* Associate 'was picked' with whatever J evalauates to */
  END

DO I = 1 TO WORDS(X.INDEX) /* Number of blank delimited 'words' */
  J = WORD(X.INDEX, I)     /* Extract 1 'word' at a time */
  SAY J X.J                /* Print 'word' and its associated value */
  END

非常简单,但是展示了这个想法。只需确保INDEX(或任何您选择的名称)用于保存索引名称时,永远不会弹出作为关联值! 如果可能的话,请使用其他变量来保存索引。

最后一点。请注意我的每个示例都以/* REXX */开头,您可能需要将其作为您在Z/OS下运行的REXX程序的第一行。


1
除此之外,您可以通过Symbol()函数来判断一个变量是否已经被设置:X=1; Say Symbol('X') /* -> 'VAR' /; Say Symbol('Y') / -> 'LIT' (表示文字) */ - Ross Patterson
我注意到所有的例子都是全部大写的。Rexx是大小写敏感的。你需要记住的是,未初始化的变量使用它们的大写名称作为它们的值。因此,x.a = 1实际上将x.A设置为1。但是,如果c='a',那么x.c会将x.a设置为一个完全独立的分支叶子,与x.A不同。 - Wes Miller
1
@Wes 复合符号的评估如下:1)词干名称转换为大写,但不进行评估。2)尾部元素(由点分隔)转换为大写,然后作为单独的符号进行评估。3)折叠的词干名称加上评估的尾部符号形成一个“新”符号。4)将“新”符号按原样(未折叠)进行评估。这种评估产生复合符号值。 继续您的示例,其中c = 'a'且符号a未分配,则复合符号:x.c、x.C、X.c和X.C都评估为相同的内容,类似地,x.a、x.A、X.a和X.A也评估为相同但不同的内容。 - NealB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接