首先需要注意的是,显示的代码是能工作的,而没有展示不起作用的修改后的代码。此外,如果只剩下一个人,为什么还需要更多选择呢?总之,实际问题不太清晰,只是说“我不知道如何在COBOL中使用OR。我不知道如何在COBOL中使用AND”。
除此之外,有两个实际问题:
1. 我让编译器难以理解吗?
2. 跳过某些东西是否有更简单的方法(是否有更清晰的写条件语句的方式)?
对于第一个问题,答案是否定的。这对于编译器来说并不困难。编译器确切地知道如何处理任何组合OR、AND(以及稍后我们将介绍的NOT)。问题是,人类编写者/读者是否能成功编写条件,以便编译器知道他们想要什么,而不仅仅是按照其规则给出结果(这些规则不考虑一行代码可能存在多种人类解释的情况)。
因此,第二个问题变成了:
如何编写复杂的条件语句,使得编译器能够理解作者的意图,并且对于任何有COBOL经验的代码阅读者也以相同的方式理解?
首先,让我们快速重新排列一下问题中的(可用)代码:
IF DL-CLASS-STANDING = 'First Yr' OR 'Second Yr'
AND GRAD-STAT-IN = ' ' OR 'X'
下面是其中一个答案中提到的建议代码:
IF (DL-CLASS-STANDING = 'First Yr' OR 'Second Yr')
AND (GRAD-STAT-IN = ' ' OR 'X')
第二个版本更清晰,但它与第一个版本相同。它没有使那段代码工作,而是让那段代码继续工作。
答案解决了条件复杂度增加的问题:括号(简单地简化复杂度是另一种可能性,但没有非工作示例很难提出建议)。
原始代码可以工作,但当需要更复杂时,就会出现问题。
建议的代码可以工作,但它并不能完全解决扩展条件复杂度的问题,因为在括号内部,它重复了扩展条件复杂度的问题。
这是怎么回事呢?
一个简单条件:
IF A EQUAL TO "B"
稍微复杂一点的条件:
IF A EQUAL TO "B" OR "C"
一个略微但不完全简化的解释是:
IF (A EQUAL TO "B" OR "C")
如果条件变得更加复杂,需要使用AND连接,这对人类来说可能很简单(编译器不会在意,它无法被欺骗):
IF (A EQUAL TO "B" OR "C")
AND (E EQUAL TO "F")
But what of this?
IF (A EQUAL TO "B" OR "C" AND E EQUAL TO "F")
将AND运算符放在括号内使得人类面临的原始问题被复制了。这是什么意思,它是如何工作的?
一个答案是:
IF (A EQUAL TO ("B" OR "C") AND E EQUAL TO "F")
也许对某些人来说更加清晰,但原始问题仍然存在于次要方面。所以:
IF A EQUAL TO "B"
OR A EQUAL TO "C"
简化一下,第一部分还有一个小问题(只需要加上AND),因此:
IF (A EQUAL TO "B")
OR (A EQUAL TO "C")
导致:
IF ((A EQUAL TO "B")
OR (A EQUAL TO "C"))
并且:
IF ((A EQUAL TO "B")
OR (A EQUAL TO C))
现在,如果有人想要使用AND进行增强,那么这将变得容易而清晰。如果在条件的某个部分的同一级别上进行操作,则仅会附加到该部分。如果在最外层级别上执行,则会同时附加到所有条件。
IF (((A EQUAL TO "B")
AND (E EQUAL TO "F"))
OR (A EQUAL TO "C"))
或者
IF (((A EQUAL TO "B")
OR (A EQUAL TO "C"))
AND (E EQUAL TO "F"))
如果有人想在括号内插入AND,该怎么办?因为括号内很简单,人们不太会这样做。如果括号内的内容已经复杂了,就会越来越复杂。似乎某些东西因为本身简单而不会变得复杂,而一些已经很复杂(不止一个元素,不能单独存在)的东西则容易被认为更加复杂而不需深思。
COBOL是一种老语言,许多用COBOL编写的旧程序仍在运行。许多COBOL程序必须进行修改或者只是阅读以理解某些内容,而这些程序往往需要多年的使用寿命。
在改变代码时,通过向条件添加内容,最好不要"干扰"条件的原始部分。如果复杂性留在括号内,那么代码需要干扰的可能性更大,这增加了理解所需的时间(它更加复杂)和更改的时间(需要更多的小心,需要更多的测试,因为代码被干扰了)。
许多旧程序将是不良实践的例子。对此除了小心处理外,没有太多可做的了。
没有任何借口去编写未来需要更多维护和关注的新代码,除非这是绝对必要的。
现在,上述示例可能被认为是冗长的。这是COBOL,对吧?需要大量打字?但是COBOL在数据定义方面给予了巨大的灵活性。作为其中一部分,COBOL具有Level 88,即条件名。
以下是上述内容的一部分数据定义:
01 A PIC X.
88 PARCEL-IS-OUTSIZED VALUE "B" "C".
01 F PIC X.
88 POSTAGE-IS-SUFFICIENT VALUE "F".
条件变为:
IF PARCEL-IS-OUTSIZED
AND POSTAGE-IS-SUFFICIENT
现在除了字面值,所有相关的字面值都有一个名称,这样程序员就可以指示它们实际的含义,以及承载该含义的实际值。如果应该向PARCEL-IS-OUTSIZED添加更多类别,则在88级上的VALUE子句将被扩展。
如果要组合另一个条件,则做到这一点要简单得多。
这是真的吗?是的。从这个角度来看。
COBOL基于编码时条件的结果运行。
If condition
通过使用括号,可以将简单条件组合成一个条件:
If condition = If (condition) = If ((condition1) operator (condition2))...
一直到编译器的极限。
人只需要处理他们想要达到目标的条件。对于一般逻辑流程,请查看If条件。对于验证,请查看最低细节。对于子集,请查看与子集相关的条件部分。
使用简单条件。通过括号使条件变得简单。在需要的情况下,通过组合简单条件来创建复杂条件。使用条件名称进行与文字值的比较。
到目前为止,OR和AND已经被处理过了。NOT通常被视为需谨慎对待的东西:
IF NOT A EQUAL TO B
IF A NOT EQUAL TO B
IF (NOT (A EQUAL TO B)), remembering that this is just IF condition
如果将NOT简化,它就不可怕了。
在整个过程中,我一直在编辑空格。因为括号存在,我喜欢让它们显眼。我喜欢结构化和缩进条件,以强调我赋予它们的含义。
所以:
IF ( ( ( condition1 )
OR ( condition2 ) )
AND
( ( condition3 )
OR ( condition4 ) ) )
(而且比那还要雕塑化)。通过结构化,我希望 a)自己减少错误 b)即使我犯错,别人也有更好的发现机会。
如果条件不简化,那么理解代码就更加困难。改变代码也更加困难。对于学习COBOL的人来说,保持简单是长期受益于所有人的。
88
语法看起来一点也不像可读的英语。 - Asaph