我现在正在学习COBOL,非常喜欢88类型的变量,我想知道在其他语言(大多数已知的语言,如C、Objective-C)中是否有类似的东西,甚至使用库。
我唯一能想到的是使用
#define booleanResult (variableName==95)
但不可能将boolenResult
设置为true
并使variableName
取95作为值。
05 nicely-named-data PIC X.
88 a-meangingful-condition VALUE "A".
88 another-meaingingful-condition
VALUE "A" "B"
"X" THRU "Z"
SPACE ZERO.
IF a-meaningful-condition
IF another-meaningful-condition
SET a-meaningful-condition TO TRUE
SET another-meaningful-condition
TO TRUE
IF测试与88(条件名称)相关的数据名称(条件变量)所引用的值,用于单个值或多个值中的一个,这些值可以包括范围(THRU)和图形常量(ZERO、SPACE、LOW-VALUES等)。
SET是1985年标准中COBOL的最新添加,它将将数据名称的值更改为88上指定的第一个值,这样,如果您在测试中立即引用88,则测试将为true。
COBOL不具有布尔值,即解析为0或1的东西,或者其他任何东西,都是false/true。
任何支持对象的语言都可以用来模仿行为。也许你甚至在没有真正意识到的情况下就已经做到了
正如NealB在评论中指出的那样,可以使用函数(或一个过程,或将控制权转移到另一个模块),但数据和对它的引用不会在一起,也不会受到意外伤害。
COBOL在定义数据结构方面具有很大的灵活性。88级是维护和理解程序以及编写程序的有力辅助。
我不知道还有哪种语言有与之相当的直接和自然的元素,但还有很多语言我不知道。
NealB在评论中再次强调了使用THRU/TROUGH来指定一系列值的重要性。
确实需要小心。尽管作者可能认为他们想要选择的数据可以用范围"010"到"090"来表示,但他们可能没有意识到编译器所做的是通过生成大于或等于"010"且小于或等于"090)的代码来包括该范围内的每一个可能值。
如果使用THRU,请确保您的数据不能包含预期范围内的任何内容。如果你的意思是"010"020"030"。。。"090"是可以的,只要数据在其入口点进行验证,这样它就永远不会包括任何干预值。
典型的例子是大型机上的"A"THRU"Z"。我们都知道作者的意思,但编译器却完全理解。您不能单独使用"A"THRU"Z"进行验证,因为在EBCDIC中,三组字母之间存在"间隙",使用"A"THRU"Z"会将这些间隙视为88的正确使用。
有些COBOL编译器中的88级别确实下降了,就是在缺少的"FALSE"中。
重复使用上述示例:
88 a-meaingingful-condition VALUE "A".
88 a-meaingingful-condition-NOT
VALUE "N".
要测试开关/标志,请使用前88。要关闭flag.switch,你必须使用第二个。不理想。有关88定义的FALSE示例,请参阅下面的链接之一。
在古代,标志/开关是用MOVE语句设置和重置的。一旦涉及MOVE,您就会遇到与尝试使用函数时相同的问题。MOVE和88级别的VALUE之间没有绑定关系。
现在,SET可以用来更改字段的值,打开或关闭标志/开关。
05 FILLER PIC X.
88 a-meaingingful-condition
VALUE "A".
88 a-meaingingful-condition-NOT
VALUE "N".
正在测试的字段甚至不需要名称(可以是FILLER或省略(隐含的FILLER))。
当然,正如NealB在下面一个链接的评论中指出的那样,人们仍然可以通过对组项目进行引用修改来使用MOVE来访问该字段。所以…
01 FILLER.
05 FILLER PIC X.
88 a-meaingingful-condition
VALUE "A".
88 a-meaingingful-condition-NOT
VALUE "N".
现在他们甚至不能使用引用修改,因为没有字段可以命名。字段的值只能来自定义上的value子句,或者来自将88之一设置为TRUE的SET语句。
在这个阶段,标志/开关的实际值变得不相关。
01 FILLER.
05 FILLER PIC X(7).
88 a-meaingingful-condition
VALUE "APPLE".
88 a-meaingingful-condition-NOT
VALUE "BICYCLE".
因为没有什么可以用来测试文字/数据名称,并且该字段不能是除SET之外的任何动词的目标,所以您不再需要检查所有表示包含N、Y、0或1的字段是否都是这样,并且它们的大小写没有错,并且这些字段中没有其他值。
我并不是建议使用苹果和自行车,只是用它们来说明这一点。
88也可以有一个用十六进制表示的值,就像任何字母数字字段一样:
88 a-meaingingful-condition VALUE X"25".
88也可以在一个组项目上指定,通常用一个比喻常数作为值:
01 a-group-item.
88 no-more-data-for-matching VALUE HIGH-VALUES.
05 major-key PIC X(10).
05 minor-key PIC X(5).
在文件匹配过程中,可以在文件末尾将键设置为高值,并且使用键仍然会导致其他文件得到正确处理(键低于此文件上的键)。
以下是SO提出的一些问题的链接,这些问题与88个级别的重要方面直接或间接相关。
COBOL 88级数据类型
cobol 中的组变量
在Cobol中;null或空";我们使用";NOT=空格[和/或]低值"?是哪一个?
是否使用前缀";否";COBOL变量中有什么特殊含义?
大写字母的COBOL数据验证?
我的第一种编程语言是Cobol,现在我使用的是c#,下面是我对Cobol 88级的解决方案:
在Cobol:
01 ws-valid-countries pic xx.
88 valid-country 'US', 'UK' 'HK'.
move ws-country to ws-valid-countries
if valid-country
perform...
在C#中
string[] ValidCountries = {"US","UK","HK"} ;
if ( ValidCountries.Contains(newCountry.Trim().ToUpper()) )
{
// do something
将其视为布尔getter(本质上与宏中一样)和setter(强制变量为相应值)。谁说COBOL在1965年不是现代的?
正如其他人所说,只是一些对象编程。哪个更强大,但远没有那么优雅。类似:
01 MY-DATASET.
05 MY-DEPARTEMENT PIC 9(2).
88 ILE-DE-FRANCE VALUES 75, 77, 78, 91 THRU 95.
可以在名为MyDataset:的类中用旧VBA粗略翻译
Public MyDepartement As Integer
Property Get IleDeFrance() As Boolean
Dim MyArray() As Variant
MyArray = Array(75, 77, 78, 91, 92, 93, 94, 95)
IleDeFrance = UBound(Filter(MyArray, MyDepartement, True)) > -1
End Property
(刚刚测试,它适用于VBA-excel2013)我让VBA尽可能简单,没有干净的getter或setter用于部门编号,只有一个公共数据。由于类是一个数据仓库,再加上针对它们的编码操作,因此您可以在内部做比简单的88级别更多的事情(这可能就是为什么这个功能不能构成更现代的语言的原因)。但代价是复杂性&可读性。
不那么优雅,因为必须专门定义数组,并且还必须指定其中的测试存在性。而这是美妙的88级所固有的。