Chapter 18 Quiz: COPY, REPLACE, and Copybook Management

Test your understanding of COBOL copybook management, the COPY statement, and the REPLACE directive. Each question is followed by a hidden answer -- try to answer before revealing it.


Question 1

What is the primary purpose of the COPY statement in COBOL?

  • a) To copy a file from one location to another at runtime
  • b) To include the contents of a copybook into the program at compile time
  • c) To duplicate a record from one file to another
  • d) To create a backup of the source program
Show Answer **b) To include the contents of a copybook into the program at compile time**. The COPY statement is a compiler-directing statement that retrieves the contents of a named copybook from a library and inserts that text into the program source before compilation. It is resolved during the text-processing phase, before syntax analysis begins. The copied text becomes part of the program as if the programmer had typed it directly.

Question 2

When is the COPY statement resolved -- at compile time or at runtime?

  • a) Runtime -- the copybook is loaded when the program executes
  • b) Compile time -- the copybook text is inserted before syntax analysis
  • c) Link time -- the copybook is resolved by the linker
  • d) Both compile time and runtime
Show Answer **b) Compile time -- the copybook text is inserted before syntax analysis**. COPY resolution is the very first phase of compilation. The compiler scans the source for COPY statements, retrieves the copybook text, applies any REPLACING clauses, and produces expanded source text. All subsequent compilation phases (syntax checking, optimization, code generation) work on the expanded source. At runtime, there is no trace of the COPY statement -- it has been completely resolved.

Question 3

What is the correct syntax for including a copybook named CUST-REC from a library called PRODLIB?

  • a) COPY CUST-REC FROM PRODLIB.
  • b) COPY CUST-REC OF PRODLIB.
  • c) INCLUDE CUST-REC IN PRODLIB.
  • d) IMPORT CUST-REC LIBRARY PRODLIB.
Show Answer **b) `COPY CUST-REC OF PRODLIB.`** The COPY statement uses the `OF` or `IN` keyword to specify the library containing the copybook. Both `OF` and `IN` are equivalent and interchangeable. `FROM`, `INCLUDE`, and `IMPORT` are not valid COBOL keywords for this purpose. The statement must end with a period.

Question 4

What does the REPLACING clause do in a COPY statement?

  • a) Replaces the entire copybook with new text
  • b) Performs text substitution on the copied text before it is inserted into the program
  • c) Replaces an old version of the copybook with a new version in the library
  • d) Deletes specified text from the copybook
Show Answer **b) Performs text substitution on the copied text before it is inserted into the program**. The REPLACING clause specifies one or more text substitution pairs. Each pair identifies text to find in the copybook (`==old-text==`) and text to replace it with (`==new-text==`). The substitution is applied to the copied text before it is merged into the program source. This allows a single copybook to be reused with different field name prefixes, data types, or other variations.

Question 5

What is the difference between COPY...REPLACING and the REPLACE directive?

  • a) They are identical in function and scope
  • b) COPY...REPLACING affects only the copied text; REPLACE affects all source text from that point forward
  • c) REPLACE can only be used inside copybooks; COPY...REPLACING can only be used in programs
  • d) COPY...REPLACING is standard COBOL; REPLACE is a vendor extension
Show Answer **b) COPY...REPLACING affects only the copied text; REPLACE affects all source text from that point forward**. COPY...REPLACING is scoped to a single COPY inclusion -- it substitutes text only within the text brought in by that specific COPY statement. The REPLACE directive is broader: it applies to all source text (both programmer-written and COPY-included) from the point where REPLACE appears until `REPLACE OFF` or another REPLACE statement. Both are standard COBOL, not vendor extensions.

Question 6

Which of the following is the most common content found in COBOL copybooks?

  • a) PROCEDURE DIVISION paragraphs
  • b) JCL statements
  • c) Record layouts (01-level data definitions with subordinate fields)
  • d) IDENTIFICATION DIVISION entries
Show Answer **c) Record layouts (01-level data definitions with subordinate fields)**. The overwhelming majority of copybooks contain data definitions -- record layouts that define the structure of files, database tables, communication areas, and parameter blocks. This ensures all programs that access a shared data structure use identical field names, sizes, positions, and data types. While copybooks can contain text from any division, record layouts are the dominant use case.

Question 7

A COPY statement must end with which punctuation mark?

  • a) Semicolon (;)
  • b) Comma (,)
  • c) Period (.)
  • d) No punctuation is required
Show Answer **c) Period (.)**. The COPY statement is a compiler-directing statement and must always end with a period. This is a mandatory rule, not optional. Forgetting the period is one of the most common COPY-related compilation errors, because the compiler will interpret subsequent source lines as part of the COPY statement's REPLACING clause or as a syntax error.

Question 8

What happens when a copybook itself contains a COPY statement?

  • a) Compilation fails -- nested COPY is not allowed
  • b) The inner COPY statement is ignored
  • c) The compiler resolves nested COPY statements recursively
  • d) The inner COPY is deferred until runtime
Show Answer **c) The compiler resolves nested COPY statements recursively**. When the text brought in by a COPY statement itself contains COPY statements, the compiler resolves them in turn. This process continues recursively until all COPY statements are resolved. This allows modular copybook design where a master copybook includes subordinate copybooks. Circular references (A copies B, B copies A) are detected by the compiler and reported as errors.

Question 9

What does the pseudo-text delimiter == == indicate in a REPLACING clause?

  • a) An equality comparison
  • b) The boundaries of a text string to be matched or substituted
  • c) A comment marker
  • d) An assignment operator
Show Answer **b) The boundaries of a text string to be matched or substituted**. Pseudo-text delimiters (`==`) mark the beginning and end of text patterns in REPLACING and REPLACE operations. For example, `==:TAG:== BY ==LOAN==` means "find the text `:TAG:` and replace it with `LOAN`". The delimiters themselves are not part of the matched or substituted text. Pseudo-text can contain multiple words, spaces, and special characters.

Question 10

How does the compiler locate a copybook when it encounters a COPY statement?

  • a) It searches the current directory only
  • b) It searches the libraries specified in the SYSLIB DD concatenation (z/OS) or include path
  • c) It downloads the copybook from a central repository at runtime
  • d) It looks for the copybook embedded within the source file
Show Answer **b) It searches the libraries specified in the SYSLIB DD concatenation (z/OS) or include path**. On z/OS, the compiler searches the datasets listed in the SYSLIB DD statement in the order they are concatenated. On GnuCOBOL, the `-I` option or `COB_COPY_DIR` environment variable specifies the search path. The first library containing a matching copybook name is used. If the copybook is not found in any library, compilation fails with an error.

Question 11

What is the primary risk of changing a copybook that is used by many programs?

  • a) The copybook file will become too large
  • b) Programs compiled with the old version will be incompatible with programs compiled with the new version
  • c) The compiler will refuse to process the changed copybook
  • d) The change will automatically propagate to all programs without recompilation
Show Answer **b) Programs compiled with the old version will be incompatible with programs compiled with the new version**. When a copybook is changed (especially record layouts), all programs that include it must be recompiled. If some programs are recompiled and others are not, the programs will have different understandings of the record structure, leading to data misalignment, field corruption, ABENDs, and incorrect processing. This is the most dangerous aspect of copybook management.

Question 12

What is the REPLACE OFF statement used for?

  • a) To disable the COPY statement
  • b) To cancel a previously active REPLACE directive
  • c) To delete a copybook from the library
  • d) To undo changes made by COPY...REPLACING
Show Answer **b) To cancel a previously active REPLACE directive**. `REPLACE OFF` terminates the text substitution that was established by a prior REPLACE statement. After `REPLACE OFF`, no further substitutions are performed on the source text (unless another REPLACE statement is encountered). It does not affect COPY...REPLACING, which is scoped to individual COPY statements and does not need explicit cancellation.

Question 13

True or False: A COPY statement can appear in the PROCEDURE DIVISION.

Show Answer **True**. A COPY statement can appear anywhere in a COBOL program where the copied text would be syntactically valid. While most COPY statements appear in the DATA DIVISION (for record layouts), it is valid to place them in the PROCEDURE DIVISION to include shared paragraphs or sections, in the ENVIRONMENT DIVISION for file control entries, or even in the IDENTIFICATION DIVISION. The compiler simply inserts the copybook text at the COPY statement's location.

Question 14

True or False: The REPLACING clause can change the PICTURE clause of a field in a copybook.

Show Answer **True**. The REPLACING clause performs simple text substitution -- it does not understand COBOL syntax or semantics. Any text in the copybook can be replaced, including PIC clauses, VALUE clauses, level numbers, or even COBOL keywords. For example:
COPY MY-FIELDS REPLACING ==PIC X(10)== BY ==PIC X(20)==.
This would change the field size from 10 to 20 characters. However, this is an unusual and potentially confusing use of REPLACING. The tag-based pattern (`:TAG:` replacement) is more common and maintainable.

Question 15

True or False: If two copybooks with the same name exist in different libraries, the compiler uses the one from the first library in the SYSLIB concatenation.

Show Answer **True**. The compiler searches the SYSLIB libraries in concatenation order and uses the first match. This is why library order matters in the compile JCL. For example, if TESTLIB is concatenated before PRODLIB and both contain CUST-RECORD, the TESTLIB version is used. This feature is intentionally used to override production copybooks with test versions during development and testing. It can also cause accidental use of wrong versions if the concatenation order is incorrect.

Question 16

True or False: COPY...REPLACING can replace text that spans multiple lines.

Show Answer **True**. Pseudo-text in a REPLACING clause can span multiple lines. For example:
COPY MY-COPY REPLACING ==05  OLD-FIELD  PIC X(10).==
                     BY ==05  NEW-FIELD  PIC X(20).==.
The compiler treats pseudo-text as a continuous string, ignoring line boundaries within the `== ==` delimiters. However, multi-line replacements are fragile because they depend on exact whitespace matching, and they are difficult to read. Single-token or tag-based replacements are preferred.

Question 17

True or False: The REPLACE directive can be used to replace text within comments.

Show Answer **False**. The REPLACE directive (and COPY...REPLACING) operate on source text, but they do not modify comment lines (lines with `*` in column 7 in fixed format, or lines starting with `*>` in free format). Comments are excluded from text substitution. This is by design -- comments should reflect the original copybook text, not the substituted version, to help with debugging and documentation.

Question 18

True or False: A copybook can contain a complete COBOL program (all four divisions).

Show Answer **True**. A copybook can contain any valid COBOL source text, including a complete program with all four divisions. When such a copybook is COPYed, the entire program text is inserted at the COPY statement's location. This is technically valid but extremely unusual and not recommended. The practical use cases for copybooks are data definitions, file control entries, and occasionally shared paragraphs -- not complete programs.

Question 19

What will the expanded source look like after this COPY statement is processed?

Copybook FILE-STATUS-CHECK:

           IF :FS: NOT = '00'
               DISPLAY ":NAME: FILE ERROR: " :FS:
               MOVE 16 TO RETURN-CODE
               STOP RUN
           END-IF

COPY statement:

           COPY FILE-STATUS-CHECK
               REPLACING ==:FS:==   BY ==WS-MAST-STATUS==
                         ==:NAME:== BY ==MASTER==.
Show Answer The expanded source will be:
           IF WS-MAST-STATUS NOT = '00'
               DISPLAY "MASTER FILE ERROR: " WS-MAST-STATUS
               MOVE 16 TO RETURN-CODE
               STOP RUN
           END-IF
Note that the REPLACING clause substitutes ALL occurrences of each tag in the copied text. `:FS:` appears twice (in the IF condition and in the DISPLAY) and both are replaced with `WS-MAST-STATUS`. `:NAME:` appears once inside a literal string and is replaced with `MASTER`. This produces a customized error-checking block for the master file. **Important:** The replacement of `:NAME:` inside the quoted string works because REPLACING operates on raw text, not on COBOL tokens. The delimiters `== ==` match any text, including text within literals.

Question 20

A programmer writes the following code. What is the problem?

       01  OLD-MASTER.
           COPY ACCT-RECORD
               REPLACING ==:PFX:== BY ==OM==.
       01  NEW-MASTER.
           COPY ACCT-RECORD
               REPLACING ==:PFX:== BY ==OM==.
Show Answer Both COPY statements use the **same replacement value** (`OM`) for the `:PFX:` tag. This means OLD-MASTER and NEW-MASTER will have identically named fields (e.g., both will contain OM-ACCOUNT-NUM, OM-BALANCE, etc.). The compiler will report **duplicate data names** because two different 01-level records contain fields with the same names. The fix is to use different prefixes:
       01  OLD-MASTER.
           COPY ACCT-RECORD
               REPLACING ==:PFX:== BY ==OM==.
       01  NEW-MASTER.
           COPY ACCT-RECORD
               REPLACING ==:PFX:== BY ==NM==.
Now OLD-MASTER has OM-ACCOUNT-NUM and NEW-MASTER has NM-ACCOUNT-NUM -- unique names that can be referenced without ambiguity.

Question 21

A bank's compile JCL has the following SYSLIB concatenation:

//SYSLIB   DD  DSN=BANK.DEVLIB,DISP=SHR
//         DD  DSN=BANK.TESTLIB,DISP=SHR
//         DD  DSN=BANK.PRODLIB,DISP=SHR

The CUSTOMER-RECORD copybook exists in all three libraries. Which version will the compiler use, and why is this potentially dangerous for a production compile?

Show Answer The compiler will use the **DEVLIB version** because it is the first library in the concatenation. The compiler searches libraries in order and uses the first match. This is potentially dangerous for a production compile because: 1. DEVLIB may contain untested, in-progress changes to CUSTOMER-RECORD 2. A developer may have added experimental fields, changed field sizes, or introduced bugs 3. The production program would be compiled with untested copybook changes, which could cause data corruption or processing errors in production For a production compile, the JCL should list PRODLIB first (or exclusively):
//SYSLIB   DD  DSN=BANK.PRODLIB,DISP=SHR
The three-library concatenation with DEVLIB first is appropriate only for development compiles.

Question 22

What is the output of the following code?

       REPLACE ==INTEREST-RATE== BY ==0.05==.
       WORKING-STORAGE SECTION.
       01  WS-RATE     PIC 9V99 VALUE INTEREST-RATE.
       01  WS-BALANCE  PIC 9(7)V99 VALUE 50000.00.
       01  WS-INTEREST PIC 9(7)V99.

       REPLACE ==INTEREST-RATE== BY ==0.08==.
       PROCEDURE DIVISION.
           COMPUTE WS-INTEREST =
               WS-BALANCE * INTEREST-RATE
           DISPLAY "RATE: " WS-RATE
           DISPLAY "INTEREST: " WS-INTEREST
           STOP RUN.
Show Answer The output is:
RATE: 0.05
INTEREST: 04000.00
Here is why: 1. The first REPLACE sets `INTEREST-RATE` to `0.05`. This applies to the VALUE clause of WS-RATE, so WS-RATE is initialized to 0.05. 2. The second REPLACE sets `INTEREST-RATE` to `0.08`, overriding the first. This applies from that point forward. 3. In the COMPUTE, `INTEREST-RATE` is replaced by `0.08`. So the computation is: 50000.00 * 0.08 = 4000.00. 4. WS-RATE displays 0.05 (its initialized value from the first REPLACE). The second REPLACE does not retroactively change the VALUE clause that was already processed under the first REPLACE. 5. WS-INTEREST displays 4000.00 (computed with the second REPLACE's rate of 0.08). This example illustrates the positional nature of REPLACE -- each REPLACE applies only to the source text that follows it.

Question 23

Examine the following copybook and COPY statement. What error will occur?

Copybook AMOUNT-FIELDS:

       05  :PFX:-AMOUNT        PIC S9(9)V99 COMP-3.
       05  :PFX:-AMOUNT-EDITED PIC -(9)9.99.

COPY statement:

       COPY AMOUNT-FIELDS
           REPLACING ==:PFX:== BY ==TOTAL==.
Show Answer The expanded source would be:
       05  TOTAL-AMOUNT        PIC S9(9)V99 COMP-3.
       05  TOTAL-AMOUNT-EDITED PIC -(9)9.99.
This is actually **correct** -- there is no error. The replacement of `:PFX:` by `TOTAL` produces valid field names. The replacement correctly applies to both occurrences. However, if the question intended to highlight a potential issue: if `:PFX:` were replaced by a very long string, the resulting field name might exceed the 30-character COBOL name limit. For example, replacing `:PFX:` with `WIRE-TRANSFER-OUTGOING` would produce `WIRE-TRANSFER-OUTGOING-AMOUNT-EDITED` (36 characters), which exceeds the limit and would cause a compilation error. This is a common gotcha with tag-based replacement patterns.

Question 24

A team discovers that 23 of their 85 programs define the customer record inline (without using a copybook) and 62 programs use the CUSTOMER-RECORD copybook. A new field must be added to the customer record. What is the impact on each group?

Show Answer **For the 62 programs using the copybook:** - Update the CUSTOMER-RECORD copybook once - Recompile all 62 programs (the new field is automatically picked up) - If the record length changed, update all FD entries (or ensure FD is also in a copybook) - Test a representative sample; all programs get the identical change **For the 23 programs with inline definitions:** - Each of the 23 programs must be individually edited to add the new field - Each edit must be reviewed to ensure the field name, PIC clause, position, and USAGE match exactly - Risk of human error: a typo in even one program creates a data mismatch - Testing must cover all 23 programs individually because each was changed independently - Total effort: approximately 23x the work of a single copybook change This scenario powerfully illustrates why copybooks exist. The 62 programs require one change + recompilation. The 23 programs require 23 individual changes, each with its own risk of error. Over time, the inline definitions tend to diverge further as different programmers make slightly different changes.

Question 25

What is the purpose of the OF (or IN) clause on a COPY statement, and when would you omit it?

Show Answer The `OF` (or `IN`) clause specifies which library contains the copybook:
COPY CUSTOMER-RECORD OF PRODLIB.
This directs the compiler to search specifically in the library named PRODLIB for the copybook. **When to omit it:** Most shops omit the OF clause and rely on the SYSLIB DD concatenation to determine the search order:
COPY CUSTOMER-RECORD.
The compiler searches all libraries in the SYSLIB concatenation until it finds a match. This is the standard practice because: 1. It decouples the program source from specific library names 2. The same source can be compiled against different libraries (dev, test, prod) just by changing the JCL 3. It avoids hardcoding library names that may change during environment migrations The OF clause is used when multiple libraries contain copybooks with the same name and you need to force a specific version. This is rare and usually indicates a naming convention problem.

Question 26

A programmer uses REPLACE to temporarily change a field name for debugging:

       REPLACE ==WS-BALANCE== BY ==WS-DEBUG-BALANCE==.
       ...100 lines of code...
       REPLACE OFF.

What are the risks of this approach?

Show Answer The risks include: 1. **Unintended substitutions:** If `WS-BALANCE` appears inside a literal string (e.g., `DISPLAY "WS-BALANCE CHECK"`) or as part of a longer name (e.g., `WS-BALANCE-FORWARD`), the REPLACE may match incorrectly. (Note: pseudo-text matching generally respects word boundaries, but edge cases exist.) 2. **Forgetting REPLACE OFF:** If the programmer forgets `REPLACE OFF`, the substitution continues through the rest of the program, affecting code that should use the original WS-BALANCE. 3. **Accidental production deployment:** If this debug REPLACE is committed to the source and compiled for production, the production program uses WS-DEBUG-BALANCE (which may not exist or may behave differently). 4. **Confusing compiler listing:** The listing shows the substituted text, but the source file shows the original. Developers reading the source see WS-BALANCE, but the executing code uses WS-DEBUG-BALANCE. 5. **Interaction with COPY...REPLACING:** If a COPY statement also replaces text, the REPLACE directive applies in addition to (and after) COPY REPLACING, which can produce unexpected compound substitutions. Better alternatives: use a debugger, add conditional DISPLAY statements, or use debug compiler options rather than REPLACE for debugging.

Question 27

True or False: The COPY statement can include text from a different programming language (e.g., SQL or CICS commands) stored in a copybook.

Show Answer **True**. A copybook is simply a file of text that gets inserted into the source. The COPY statement does not validate the content -- it just performs text insertion. If a copybook contains EXEC SQL or EXEC CICS statements, those are perfectly valid because the SQL or CICS precompiler processes them before or after the COBOL compiler's text phase (depending on the compilation sequence). In practice, SQL INCLUDE (EXEC SQL INCLUDE copybook-name END-EXEC) is often used instead of COPY for database record layouts because the SQL precompiler resolves it. But using COBOL COPY for SQL-related copybooks is also valid.

Question 28

What output does the following produce?

       WORKING-STORAGE SECTION.
       01  WS-MSG    PIC X(30).

       PROCEDURE DIVISION.
           MOVE "ORIGINAL" TO WS-MSG
           DISPLAY WS-MSG
           COPY MSG-UPDATE.
           DISPLAY WS-MSG
           STOP RUN.

Where copybook MSG-UPDATE contains:

           MOVE "UPDATED BY COPYBOOK" TO WS-MSG
Show Answer The output is:
ORIGINAL
UPDATED BY COPYBOOK
Even though the COPY statement appears to be in the middle of the PROCEDURE DIVISION, it is resolved at compile time. After COPY resolution, the expanded source looks like:
       PROCEDURE DIVISION.
           MOVE "ORIGINAL" TO WS-MSG
           DISPLAY WS-MSG
           MOVE "UPDATED BY COPYBOOK" TO WS-MSG
           DISPLAY WS-MSG
           STOP RUN.
The first DISPLAY shows "ORIGINAL". Then the MOVE from the copybook changes WS-MSG. The second DISPLAY shows "UPDATED BY COPYBOOK". This demonstrates that copied PROCEDURE DIVISION code executes in sequence just like any other code.

Question 29

A bank has a standard 80-byte customer record. The CUSTOMER-RECORD copybook is used by 100 programs. A new requirement adds a 20-byte email field, making the record 100 bytes. What is the safest implementation strategy?

  • a) Add the field to the copybook and recompile all 100 programs at once
  • b) Create a new CUSTOMER-RECORD-V2 copybook and gradually migrate programs
  • c) Add the field to existing FILLER space if available, keeping the record at 80 bytes
  • d) Store the email in a separate file linked by customer ID
Show Answer The safest strategy depends on the situation, but **c) and d)** are the safest short-term options: **c) Use existing FILLER space** -- if the original record has 20+ bytes of FILLER, the new field can replace part of the FILLER without changing the record length. All programs continue to work because the record is still 80 bytes. Programs that need the email field must be recompiled, but programs that do not need it continue working without recompilation. **d) Separate file** -- adding a companion file avoids any change to the existing record. This is the safest approach when no FILLER space is available and when simultaneous recompilation of 100 programs is not feasible. **a) Big-bang recompilation** is correct but risky -- it requires coordinating 100 program changes, VSAM file redefinition, and simultaneous deployment. If any program is missed, data corruption results. **b) Versioned copybooks** lead to long-term technical debt (two copybook versions to maintain) and do not solve the fundamental problem of mixed record lengths. In practice, most shops with good change management use option (a) with thorough impact analysis and a planned deployment window.

Question 30

A junior developer creates a copybook that defines a field and also performs a MOVE:

       05  WS-INIT-DATE   PIC X(8).
           MOVE FUNCTION CURRENT-DATE(1:8) TO WS-INIT-DATE.

The developer places a COPY statement for this in the WORKING-STORAGE SECTION. What happens?

Show Answer **The program will fail to compile**. The MOVE statement is a PROCEDURE DIVISION statement, but it is being copied into the WORKING-STORAGE SECTION (a DATA DIVISION section). The COBOL compiler expects only data definitions (level numbers, PIC clauses, VALUE clauses) in WORKING-STORAGE. A MOVE statement is syntactically invalid in this location. The correct approaches are: 1. Use a VALUE clause for initialization: `05 WS-INIT-DATE PIC X(8) VALUE SPACES.` and perform the MOVE in the PROCEDURE DIVISION. 2. Split the copybook into a data-definition copybook (for WORKING-STORAGE) and a separate initialization copybook (for PROCEDURE DIVISION). 3. Use the data definition in the copybook and write the initialization code in the program's PROCEDURE DIVISION. This is a common pitfall when mixing data definitions and procedural code in copybooks -- the COPY statement inserts text literally, regardless of whether it is valid at the insertion point.