Scope Terminators
A D V E R T I S E M E N T
In the section
COBOL basics I mentioned the full stop (period). This is what can be
described as a scope terminator. Many COBOL verbs have their own scope
terminator, for example, END-IF, END-READ, END-PERFORM etc... The purpose of a
scope terminator is to define when a verb's scope (i.e. associated logic) is
finished.
For example:
READ IN-FILE
AT END MOVE 'Y' TO EOF FLAG
NOT AT END
IF REC-IN = 'Z' THEN
PERFORM PROCEDURE-X
END-IF
END-READ
[more code]
In the above example END-READ defines the scope of the
READ statement since there is a condition involved (AT END of the file, or NOT
AT END of the file), while END-IF defines then end of the IF condition, i.e.
END-READ and END-IF define their scope. Any code that follows the read statement
will apply regardless of the READ condition (which is what you would want in the
above example). Without END-READ the subsequent code would only be performed
while NOT AT END is true: some nasty bugs could ensue! Things become even more
scary if you forget to use END-IF or END-PERFORM (especially when looping).
There's a good chance the compiler might pick up the error.
However, a period is also a scope terminator. You might
also code:
READ IN-FILE
AT END MOVE 'Y' TO EOF FLAG
NOT AT END
PERFORM UNTIL REC-IN = 'A'
IF REC-IN = 'Z' THEN
PERFORM PROCEDURE-X.
END-PERFORM
[more code]
|
This would have the same effect as the first example
(assuming the compiler doesn't complain). Some people do use periods in place of
END-IF etc (note: I'm not sure you allowed to replace END-PERFORM however).
Problems may arise when you forget to use a scope terminator somewhere and
there's a period somewhere further down the code then the compiler might just
get confused.
It is important to realise that the
period will terminate all ongoing conditions. So in the above
example, the period will act as both an END-IF, END-PERFORM and END-READ.
Look at this paragraph:
000090*this works, using period scope terminators
000100 PARAGRAPH-ABC.
000200 MOVE 0 TO N
000300 PERFORM UNTIL N > 10
000400 COMPUTE N = N + 1
000500 DISPLAY N.
000600
000700 PERFORM PROCEDURE-Y N TIMES
000800 PERFORM UNTIL END-OF-FILE
000900 READ IN-FILE
001000 AT END MOVE 'Y' TO EOF-FLAG
001100 NOT AT END
001200 ADD VALUE-FROM-RECORD TO N GIVING X.
001300
001400 END-PERFORM
001500 DISPLAY X.
|
In the first example, the code will display numbers 1 to
10. It will then perform PROCEDURE-Y 11 times. Finally, the numbers coming from
the IN-FILE (VALUE-FROM-RECORD) will be added to 11 giving X, which is then
displayed.
But what if we were to forget to put a period at the end
of line 500?
000090*this has a syntax error
000100 PARAGRAPH-ABC.
000200 MOVE 0 TO N.
000300 PERFORM UNTIL N > 10
000400 COMPUTE N = N + 1
000500 DISPLAY N
000600
000700 PERFORM PROCEDURE-Y N TIMES.
000800 PERFORM UNTIL END-OF-FILE
000900 READ IN-FILE
001000 AT END MOVE 'Y' TO EOF-FLAG
001100 NOT AT END
001200 ADD VALUE-FROM-RECORD TO N GIVING X.
001300
001400 END-PERFORM
001500 DISPLAY X.
|
Now, the period on line 700 will terminate the scope of
the PERFORM statement on line 300. This means that PROCEDURE-Y gets performed
1+2+3+4+5+6+7+8+9+10+11 times (that's 66 times!). Oh dear.
In fact, when I tried to test these code fragments by
compiling [on the Fujitsu COBOL v3] it complained bitterly! The compiler was
particularly bothered by the lack of END-PERFORMS.
I was taught to only use 2 periods in any
paragraph: the first after the paragraph name, the second (and last) at the end
of the paragraph. So always use the verb's own scope terminator. More typing but
less headaches in my humble opinion. Here's what the above code would look like
when following this advice:
000090*using just 2 periods
000100 PARAGRAPH-ABC.
000200 MOVE 0 TO N
000300 PERFORM UNTIL N > 10
000400 COMPUTE N = N + 1
000500 DISPLAY N
000600 END-PERFORM
000700 PERFORM PROCEDURE-Y N TIMES
000800 PERFORM UNTIL END-OF-FILE
000900 READ IN-FILE
001000 AT END MOVE 'Y' TO EOF-FLAG
001100 NOT AT END
001200 ADD VALUE-FROM-RECORD TO N GIVING X
001300 END-READ
001400 END-PERFORM
001500 DISPLAY X.
|
|