cobol
COBOL是编程语言的Rodney Dangerfield,它不受任何尊重。 它经常因其冗长而被贬低,并被认为是过时的。 然而,COBOL 绝非一成不变的语言 。 它估计处理所有业务交易的85%,并且每年编写50亿行新的COBOL代码。
我作为COBOL程序员工作了10年,但我认为它的声誉不会像人们认为的那样糟糕。 实际上,它非常擅长处理货币和固定格式的记录。 但是COBOL确实有其怪癖,其中许多根源在于编程初期的计算环境。 这是关于打Kong卡如何吃掉我的程序的故事。
一个神秘的错误
这是问题代码的示例,该代码尝试计算订单的运费和预计的运送日期:
1 identification division .
2 program-id .
3 test-ship .
4
5 data division .
6 working-storage section .
7
8 01 shipping-method pic x ( 2 ) value 'US' .
9 01 cust-type pic x ( 2 ) value 'EM' .
10 01 normal-ship-date-yyyymmdd pic 9 ( 8 ) value 20170522 .
11 01 nextday-ship-date-yyyymmdd pic 9 ( 8 ) value 20170508 .
12 01 expected-shipping-date pic 9 ( 8 ) .
13 01 shipping-charge pic 99v99 value 4.99 .
14
15 procedure division .
16 if shipping-method <> 'FX'
17 move normal-ship-date-yyyymmdd to expected-shipping-date
18 else
19 move nextday-ship-date-yyyymmdd to expected-shipping-date .
20
21 if cust-type = 'EM'
22 move 0 to shipping-charge .
23
24 display expected-shipping-date .
25 display shipping-charge .
即使您以前从未看过COBOL代码,其逻辑也应易于遵循。 如果运送方式为“ FX”,则客户将获得第二天的运送,否则运送需要两个星期。 (这是90年代。)员工获得免费送货; 其他所有人支付$ 4.99。 该代码对我来说看起来是正确的,但是有一个错误-发货日期计算正确,但是向员工收取了全部运费。
问题出在19点末。那个时候,它花费了一些侦探性的工作才能找到答案,但是现代语法高亮的编辑器会立即对其进行标记。 但是为什么这是一个问题呢? 当COBOL对第22行结尾处的那个完全满意时,为什么不喜欢那个时期呢?
句子代替障碍
要回答这个问题,我们需要回到1950年代后期的COBOL起源。 在此之前,大多数语言都是为解决科学和工程问题而设计的,因此它们的语法类似于数学方程式。 (Fortran是这种语言的经典示例。)另一方面,COBOL则用于业务计算。 为了使外行人更容易学习,Grace Hopper和她的国防部团队以及IBM工程师为COBOL提供了英语语法。 COBOL程序具有大多数结构,而不是大多数现代语言具有的递归语法。 COBOL而不是块,将语句组合在一起成为“句子”。 就像英语一样,每个句子都以句点结尾。
尽管从理论上讲这似乎是个好主意,但实际上却是有问题的。 由于流浪期可能会意外终止一个块,因此很难四处移动代码。 周期也很难注意到-在90年代的CRT终端上它们通常只是一个像素。 但是这里存在一个更深层次的问题,一个与最初开发COBOL时程序员如何编写代码有关的问题。
打卡
COBOL打Kong卡 ,Rainer Gerhards, CC BY-SA 3.0
设计COBOL时,硬盘的价格过高,因此大多数程序都是在打Kong卡上编写的。 最常见的打Kong卡由12×80网格组成,其中Kong表示1,非Kong表示0。每列是单个12位字符,每张卡是单个80个字符的文本行。 要运行程序,您需要将一副打Kong卡放入读卡器中。 每张卡的前六列和最后八列保留用于序列号和标识符。 这样,如果您放下甲板(可能是您程序的唯一副本),则可以通过机械分拣机喂入卡片,以将卡片放回正确的顺序。
这意味着COBOL会忽略第72列之后的任何字符。如果恰好是一个句点,则代码的整个逻辑可能会更改。 而且,正如您现在无疑已经猜到的那样,第19行的那个时期在第73列。这是COBOL编译器实际上解释这些行的方式:
16 if shipping-method <> 'FX'
17 move normal-ship-date-yyyymmdd to expected-shipping-date
18 else
19 move nextday-ship-date-yyyymmdd to expected-shipping-date
20
21 if cust-type = 'EM'
22 move 0 to shipping-charge .
一旦发现问题所在,修复起来就很容易:我从第19行的开头删除了一个空白字符,将句点放在第72列。尽管我以前从未遇到过,但这是一个常见的错误许多大型机COBOL程序员会在其终端的第72和73列之间绑一条线程。
今天的COBOL
COBOL-85标准添加了范围终止符(例如end-if) ,因此不再需要句号来结束句子。 尽管许多编译器早在此之前就已支持,但COBOL 2002标准允许使用自由格式的代码。 写入2002标准的相同代码看起来更像是现代编程语言:
16 if shipping-method <> 'FX'
17 move normal-ship-date-yyyymmdd to expected-shipping-date
18 else
19 move nextday-ship-date-yyyymmdd to expected-shipping-date
20 end-if
21
22 if cust-type = 'EM'
23 move 0 to shipping-charge
24 end-if
注意,行首的空白也不再需要。 我通常使用的系统同时支持范围终止符和自由格式代码,因此,在必须对另一个系统进行一些更改之前,我从未遇到过此问题。
对于开源爱好者来说,了解COBOL一直很困难。 传统上,COBOL编译器是开源且昂贵的,并且大多数COBOL代码是在公司环境中编写的。 但是,一个名为OpenCOBOL的开源编译器的工作始于2002年。2013年,它被正式接受为GNU软件包,并更名为GnuCOBOL。 要了解有关GnuCOBOL的更多信息,包括访问400页的程序员指南,请访问项目的主页 。
在Walt Mankowski的演讲“ Punch Card Ate My Program”中了解有关COBOL的更多信息! ,于8月26日在费城举行的FOSSCON上。
翻译自: https://opensource.com/article/17/8/what-about-cobol
cobol