היסטוריית עדכונים (גרסה ראשונה, פורסמה בתאריך 17 Mar 2026)
- פרסום ראשון
לצטט את המאמר הזה(DOI: 10.5281/zenodo.22173606)
מאמר זה מאוחסן בארכיון Zenodo. להלן גם ה-DOI שתמיד מפנה לגרסה האחרונה וגם ה-DOI המקובע לגרסה שאתם קוראים.
Go Komura (2026). מה צריך לדעת לפני שקוראים קוד COBOL. KomuraSoft LLC. https://doi.org/10.5281/zenodo.22173606 https://comcomponent.com/he/blog/cobol-minimum-reading-guide/
- DOI (הגרסה האחרונה)
- 10.5281/zenodo.22173606
- DOI (הגרסה הזו)
- 10.5281/zenodo.22173607
handover, טיפול בתקלה, תחזוקת חבילה של vendor. במצבים כאלה יכול לקרות שיום אחד נוחת עליכם קוד COBOL.
- שם הקובץ
.cblאו.cpy - שמות המשתנים כולם באותיות גדולות
01,05,77,88בשורה- מופיע משהו כמו
PIC S9(7)V99 COMP-3— בין לחש לתוכנת הנהלת חשבונות - ובנוסף הכול מלא ב-
COPY, ומהקובץ הפתוח לבד לא רואים את התמונה
בשלב הזה רוב האנשים עוצרים לרגע.
אבל המפה לקריאה לא כל כך גדולה. יש הבדלים בין compilers ומוצרים, אבל השלד שצריך לתפוס קודם במערכת עסקית קיימת די משותף. כאן, עם COBOL ממשפחת IBM וקוד COBOL עסקי טיפוסי בראש, נעבור על הסט המינימלי למי שנחת פתאום על הקוד.
flowchart TB
accTitle: למה עוצרים, וכמה גדולה המפה
accDescr: שמות באותיות גדולות, מספרי רמה, PIC S9(7)V99 COMP-3, והרבה COPY שלא מראים את התמונה גורמים לעצור. אבל השלד לקריאת מערכת עסקית די משותף, והמפה לא גדולה.
iv1["רישום לא מוכר עוצר"] --> iv2["אבל השלד משותף בין compilers"]
iv2 --> iv3["קודם מחזיקים רק את המפה המינימלית"]
iv1 -.-> iv4["הרבה COPY, לא רואים את התמונה"]
איור 1: מה שנראה כמו לחש מתרכז בכמה מושגים משותפים.
1. קודם המסקנה (במשפט)
אם אומרים את זה בגסות, אבל שימושי בשטח:
- COBOL היא, לפני שהיא שפת לוגיקה, שפה שמתמקדת חזק ב-הגדרת records
PROCEDURE DIVISIONלבד נותן רק חצי מהתמונה. קודם פותחיםDATA DIVISIONPICהוא צורת השדה,USAGEהוא באיזה ייצוג הוא נשמרCOMP-3הוא packed decimal. נפוץ בעולם סכומים ומונים88אינו משתנה נפרד. זה condition-name לערך של השדה שמעליוREDEFINESהוא מבט אחר על אותו זיכרון. זו לא copy- אם יש
COPY, הקובץ הפתוח עדיין לא שלם. בלי copybook אין תמונה מלאה - אם עוקבים אחרי
PERFORM,IF,EVALUATE,READ,WRITE,CALL— תופסים פחות או יותר את הזרימה - קוד ישן הוא fixed format שבו לעמודות יש משמעות. הרווח שנראה עיצוב הוא חלק מהתחביר1
בקיצור: DIVISION, PIC, USAGE, COMP-3, REDEFINES, OCCURS, 88, COPY, PERFORM. אם אלה נקראים, שיעור ההיאבדות יורד חזק.
ב-diagram, solid line מציינת relation שתמיד מתקיים ו-dashed line מציינת relation מותנה (התנאים מופיעים בהסבר של כל relation ב-detail page). הרשימה המלאה של ה-relations (סה”כ 21, כולל evidence ו-certainty) וההגדרות של ה-concepts המרכזיים נמצאות ב-detail page של ה-knowledge map (ביפנית). Data: JSON-LD / Turtle
2. COBOL היא קודם כל שפת “צורת הנתונים”
עם הראש של C# או Java, קודם רוצים לעקוב אחרי if, for וקריאות לפונקציות.
ב-COBOL עדיף לעצור לפני זה ולתפוס איזה records התכנית מקבלת, איזה records היא מייצרת, ואילו buffers יש לה.
COBOL עסקי טיפוסי רץ בערך כך:
- קורא record מקובץ או מ-DB
- שם אותו בשדות ב-
WORKING-STORAGE - עושה הסתעפות
- ממלא record אחר
- כותב החוצה
כלומר: layout לפני אלגוריתם.
flowchart TB
accTitle: הזרימה הטיפוסית של COBOL עסקי
accDescr: קוראים record מקובץ או DB, שמים ב-WORKING-STORAGE, מסתעפים, ממלאים record אחר וכותבים החוצה.
f1["קוראים record"] --> f2["שמים ב-WORKING-STORAGE"]
f2 --> f3["מסתעפים"]
f3 --> f4["ממלאים record אחר"]
f4 --> f5["כותבים החוצה"]
איור 2: הגיבור הוא זרימת ה-records. האלגוריתם יושב ביניהם.
למשל, שלד כזה:
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE01.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SALES-FILE ASSIGN TO ...
DATA DIVISION.
FILE SECTION.
FD SALES-FILE.
01 SALES-REC.
05 SALE-ID PIC 9(8).
05 SALE-AMOUNT PIC S9(7)V99 COMP-3.
WORKING-STORAGE SECTION.
01 WS-EOF PIC X VALUE 'N'.
88 EOF VALUE 'Y'.
PROCEDURE DIVISION.
PERFORM UNTIL EOF
READ SALES-FILE
AT END
SET EOF TO TRUE
NOT AT END
PERFORM PROCESS-SALE
END-READ
END-PERFORM
STOP RUN.
כשקוראים את זה, לפני PERFORM כדאי לראות את הטיפוס של SALE-AMOUNT ואת המשמעות של EOF.
COBOL נרגעת ברגע שקוראים בסדר הזה.
3. קודם ארבעת ה-DIVISION
קוד COBOL מתחלק קודם לארבעה DIVISION.
| DIVISION | מה בודקים קודם |
|---|---|
IDENTIFICATION DIVISION |
שם התכנית, הערות ישנות, מקור |
ENVIRONMENT DIVISION |
קבצים, משאבים חיצוניים, הנחות I/O |
DATA DIVISION |
הגדרות records, אזור עבודה, ארגומנטים |
PROCEDURE DIVISION |
סדר הפעולות עצמו |
במיוחד אלה חשובים:
FILE SECTIONהגדרות records של קבצי I/OWORKING-STORAGE SECTIONמשתנים יומיומיים, דגלים, מונים, buffersLOCAL-STORAGE SECTIONלפעמים יש אזור שמתאפס בכל קריאהLINKAGE SECTIONלפעמים יש ארגומנטים שמגיעים מבחוץ, או נקודת כניסה לתת-תכנית
אם רואים LINKAGE SECTION ו-PROCEDURE DIVISION USING ..., התכנית כנראה לא עומדת לבד — היא מקבלת נתונים מבחוץ.
flowchart TB
accTitle: מה מראה LINKAGE SECTION
accDescr: LINKAGE SECTION ו-PROCEDURE DIVISION USING אומרים שהתכנית כנראה מקבלת נתונים מבחוץ ולא עומדת לבד.
lk1["יש LINKAGE SECTION"] --> lk3["כנראה מקבלת נתונים מבחוץ"]
lk2["יש PROCEDURE DIVISION USING"] --> lk3
lk3 -.-> lk4["לא תכנית עצמאית"]
איור 3: אם רואים נקודת כניסה, קוראים מתוך הנחה שיש קורא.
4. לא להיבהל מ-fixed format
ב-COBOL ישן, מיקום העמודה עצמו הוא חלק מהתחביר. בלי זה, “למה יש רווח מוזר משמאל” נשאר חידה לנצח.1
ב-fixed format זה בערך כך:
- עמודות 1–6: מספר סידורי
- עמודה 7: indicator
- עמודות 8–11: Area A
- עמודות 12–72: Area B
עמודה 7 חשובה במיוחד.
*או/: שורת הערה-: שורת המשךD: debugging line*>: הערה שאפשר לכתוב גם באמצע
עם סרגל זה נראה כך. השורה הראשונה היא ספרת העשרות, השנייה ספרת היחידות.
1 2 3 4 5 6 7 8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
SSSSSSIAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB........
S= מספר סידורי (עמודות 1–6)I= indicator (עמודה 7)A= Area A (עמודות 8–11)B= Area B (עמודות 12–72).= מעמודה 73 והלאה. בחלק מה-compilers זה שדה זיהוי, אבל זה לא חלק ממשמעות התכנית
על קוד אמיתי זה נראה כך:
000100* זו שורת הערה כי עמודה 7 היא *
000200 IDENTIFICATION DIVISION.
000300 PROGRAM-ID. SAMPLE01.
000400 DATA DIVISION.
000500 WORKING-STORAGE SECTION.
000600 01 WS-ORDER.
000700 05 WS-ORDER-ID PIC 9(8).
000800 05 WS-LONG-NAME PIC X(30) VALUE 'ABCDEFGHIJKLMNOPQRST
000900- 'UVWXYZ0123'.
ארבע נקודות קריאה:
- עמודות 1–6 הן מספר סידורי. בדוגמה זה
000100ודומיו. זה לא משפיע על הריצה. לפעמים זה ריק. - עמודה 7 היא indicator.
*= הערה,-= המשך. בדוגמה שורה000900ממשיכה את ה-string literal מהשורה הקודמת. - עמודות 8–11 הן Area A. מכאן מתחילים
DIVISION,SECTION, שמות פסקאות,FD, ומספרי רמה01ו-77. בדוגמהIDENTIFICATION DIVISION.ו-01 WS-ORDER.מתחילים ב-Area A. - עמודות 12–72 הן Area B. משפטים רגילים ורמות נמוכות כמו
05. בדוגמה05 WS-ORDER-IDמתחיל ב-Area B.
הרווח כאן הוא לא “עיצוב מודרני”. חלק ממנו הוא תחביר. המרת tabs, יישור לשמאל, או copy-paste גס — שוברים את זה בקלות. כשפותחים קוד ישן, קודם בודקים אם הקובץ הוא fixed format או free format. auto-format מודרני על fixed שובר את הגבול בין Area A ל-Area B, וה-compile נופל.
flowchart TB
accTitle: לפני שנוגעים ב-fixed format
accDescr: בקוד ישן קודם בודקים fixed או free. ב-fixed מיקום העמודה הוא תחביר. auto-format או המרת tabs שוברים את הגבול בין Area A ל-Area B, וה-compile נופל.
fx1["פתחנו קוד ישן"] --> fx2{"fixed או free?"}
fx2 -->|"fixed format"| fx3["מיקום העמודה הוא תחביר"]
fx3 -.-> fx4["auto-format והמרת tabs שוברים"]
fx2 -->|"free format"| fx5["מגבלת העמודות רכה יותר"]
איור 4: לפני עיצוב, מקבעים את פורמט הקובץ.
5. המינימום של DATA DIVISION
5.1 מספרי רמה
הגדרת הנתונים ב-COBOL בונה היררכיה לפי מספר רמה, לא לפי הזחה.2
01 WS-ORDER.
05 WS-ORDER-ID PIC 9(8).
05 WS-AMOUNT PIC S9(7)V99 COMP-3.
05 WS-STATUS PIC X.
88 WS-OK VALUE '0'.
88 WS-ERROR VALUE '9'.
77 WS-COUNT PIC 9(4).
מספיק לזכור את זה:
01: הרשומה או הקבוצה ברמה העליונה02–49: הרמות מתחת77: שדה בודד עצמאי88: condition-name. שם לערך של השדה שמעליו366: ל-RENAMES. לא נפוץ, אבל קיים
הנקודה: לא לחשוב על 88 כ-משתנה bool נפרד.
אין אזור נפרד בשם WS-OK. כש-WS-STATUS הוא '0', אפשר לקרוא לזה WS-OK.
flowchart TB
accTitle: מה זו רמה 88
accDescr: רמה 88 אינה משתנה bool עצמאי. זה condition-name לערך של השדה שמעליו. כש-WS-STATUS הוא ערך מסוים, השם WS-OK נהיה true.
cn1["שדה הבסיס WS-STATUS"] --> cn2{"מה הערך?"}
cn2 -->|"0"| cn3["true בשם WS-OK"]
cn2 -->|"9"| cn4["true בשם WS-ERROR"]
cn3 -.-> cn5["אין אזור נפרד"]
איור 5: 88 אינו משתנה. זה כינוי קריא לערך.
עוד נקודה: את ההיררכיה קובע מספר הרמה, לא הרווח.
ההזחה עוזרת לעין, אבל מה שסומכים עליו בסוף הוא 01 / 05 / 10 / 88.2
5.2 PICTURE
PIC מתאר את צורת השדה.
הנפוצים:
| סימון | בערך |
|---|---|
X |
תו |
9 |
ספרה |
S |
עם סימן |
V |
נקודה עשרונית לוגית בלבד |
X(10) |
10 תווים |
9(5) |
5 ספרות |
S9(7)V99 |
עם סימן, 7 שלמות + 2 עשרוניות |
למשל:
PIC X(10)→ 10 תוויםPIC 9(5)V99→ 5 שלמות + 2 עשרוניותPIC S9(7)V99→ עם סימן, 7 שלמות + 2 עשרוניות
כאן V חשוב במיוחד.
V לא מחזיק תו . אמיתי.
PIC 9(5)V99 מטופל כמספר עם 2 ספרות אחרי הנקודה, אבל בנתונים אין נקודה.
אם מפרשים dump כ”מחרוזת שנראית כמו מספר” — זה בדרך כלל נופל.
flowchart TB
accTitle: V הוא נקודה לוגית
accDescr: ב-PIC 9(5)V99 ה-V הוא נקודה עשרונית לוגית. אין תו נקודה בנתונים. אם מפרשים קובץ או dump כמחרוזת ויזואלית, זה נופל.
vd1["PIC 9(5)V99"] --> vd2["מטופל כמספר עם 2 ספרות אחרי הנקודה"]
vd2 --> vd3["אין תו נקודה בנתונים"]
vd3 -.-> vd4["פירוש כמחרוזת ויזואלית נופל"]
איור 6: הנקודה העשרונית יושבת בהגדרה, לא בנתונים.
5.3 USAGE / DISPLAY / COMP / COMP-3
אם PIC הוא הצורה, USAGE הוא באיזה ייצוג זה נשמר.
מספיק לתפוס את אלה כדי לקרוא הרבה.45
| סימון | בערך | מה לשים לב אליו בקריאה |
|---|---|---|
DISPLAY |
עשרוני חיצוני שנראה כתווים | ב-mainframe לפעמים מניחים EBCDIC6 |
COMP / BINARY |
בינארי | מספר הספרות ב-PIC והייצוג הפנימי הם דברים שונים |
COMP-3 / PACKED-DECIMAL |
packed decimal | כטקסט זה נראה שבור |
למשל:
01 WS-AMOUNT-DISP PIC S9(7)V99.
01 WS-AMOUNT-BIN PIC S9(7) COMP.
01 WS-AMOUNT-PACK PIC S9(7)V99 COMP-3.
שלושתם “מספר”, אבל הדרך שבה הם יושבים בזיכרון שונה.
flowchart TB
accTitle: אותו מספר, ייצוג אחר
accDescr: גם באותו מספר עם סימן, DISPLAY הוא עשרוני חיצוני שנראה כתווים, COMP הוא בינארי, COMP-3 הוא packed decimal. USAGE משנה את רצף הבייטים.
us1["שדה מספרי באותה צורה"] --> us2["DISPLAY (נראה כתווים)"]
us1 --> us3["COMP (בינארי)"]
us1 --> us4["COMP-3 (packed decimal)"]
us4 -.-> us5["כטקסט זה נראה שבור"]
איור 7: PIC זהה, USAGE שונה — רצף הבייטים הוא דבר אחר.
בשטח, הרפלקס החשוב ביותר הוא ברגע שרואים COMP-3:
- זה packed decimal
- כנראה סכום, מס, מונה, תעריף
- כטקסט זה נראה שבור, וזה צפוי
- dump בתחושה של CSV או UTF-8 הוא תאונה
עם זה לא נבהלים מ-dump או מקובץ בינארי.
flowchart TB
accTitle: הרפלקס ברגע שרואים COMP-3
accDescr: COMP-3 הוא packed decimal, כנראה סכום או מונה או תעריף. כטקסט זה נראה שבור וזה צפוי. לא מסתכלים על זה כמו CSV או UTF-8.
cp1["מצאנו COMP-3"] --> cp2["זה packed decimal"]
cp2 --> cp3["חושדים בשדה סכום או מונה"]
cp3 --> cp4["לא נבהלים אם זה נראה שבור כטקסט"]
איור 8: הרפלקס הזה לבד מוריד את מספר הפעמים שנבהלים מול dump.
איך נראה COMP-3 בבייטים
שווה לעקוב אחרי זה פעם אחת ביד. אחר כך ה-dump נראה אחרת.
ל-packed decimal יש רק שני כללים.45
- דוחסים שתי ספרות עשרוניות לבייט אחד
- אבל הבייט הימני ביותר מחזיק ספרה אחת + סימן
הסימן הוא 4 ביטים: C חיובי, D שלילי, F בלי סימן.
בודקים מול דוגמה במדריך של IBM.4
| הגדרה | ערך | בייטים |
|---|---|---|
PIC S9(4) PACKED-DECIMAL |
+1234 |
01 23 4C |
PIC S9(4) PACKED-DECIMAL |
-1234 |
01 23 4D |
PIC 9(4) PACKED-DECIMAL |
1234 |
01 23 4F |
1234 הוא 4 ספרות, אז בגלל כלל 2 נשארת ספרה פנויה בהתחלה. זה ה-0 הראשון.
באותו אופן, PIC S9(7)V99 COMP-3 שחוזר במאמר:
S9(7)V99הוא 7 שלמות + 2 עשרוניות = 9 ספרותVרק מסמן איפה הנקודה, לא צורך בייט- 9 ספרות, שתיים לבייט = 4 בייטים, ועוד ספרה + סימן בבייט אחד. סה”כ 5 בייטים
אם הערך הוא +12345.67, 9 ספרות זה 001234567:
ערך : +12345.67
9 ספרות : 0 0 1 2 3 4 5 6 7 וסימן
בייטים : 00 12 34 56 7C
^ סימן C = חיובי
לערך שלילי -12345.67 רק הסוף נהיה 7D.
בייטים : 00 12 34 56 7D
ומה רואים אם פותחים את זה כטקסט? אם מנסים למפות 00 12 34 56 7C תו-לבייט ל-ASCII:
00הוא NUL,12הוא תו בקרה — בכלל לא מוצג כתו34הוא4,56הואV,7Cהוא|
על המסך זה נראה כמו “כמה תווים שלא מוצגים ואז 4V|”. הרצף 12345.67 לא מופיע בשום מקום.
זה “נראה garbled אבל לא שבור”. כשפותחים dump ורואים רצף חסר משמעות, קודם חושדים ש-USAGE של השדה הוא COMP-3.
flowchart TB
accTitle: איך בונים את הבייטים של COMP-3
accDescr: ב-packed decimal דוחסים שתי ספרות לבייט, והבייט הימני מחזיק ספרה אחת וסימן. מספר בן 9 ספרות תופס 5 בייטים. כ-ASCII, הרצף המקורי של המספר לא מופיע.
pk1["שתי ספרות לבייט"] --> pk2["הבייט האחרון: ספרה אחת + סימן"]
pk2 --> pk3["9 ספרות = 5 בייטים"]
pk3 --> pk4["כ-ASCII המספר המקורי לא מופיע"]
pk4 -.-> pk5["נראה garbled אבל לא שבור"]
איור 9: שני כללי הדחיסה הופכים dump חסר משמעות לרצף שאפשר לקרוא.
בדרך, טבלת המרה מספר-ספרות לבייטים. מספר הבייטים הוא מספר ה-9 ב-PIC, חלוקה ב-2 עם עיגול כלפי מטה, ועוד 1.
| מספר ה-9 ב-PICTURE | בייטים ב-COMP-3 |
|---|---|
| 1 | 1 |
| 2–3 | 2 |
| 4–5 | 3 |
| 6–7 | 4 |
| 8–9 | 5 |
| 10–11 | 6 |
| 12–13 | 7 |
שתי כמויות ספרות נופלות לאותו מספר בייטים כי רק כשמספר ה-9 זוגי נשארת ספרה פנויה בהתחלה. לכן S9(4) הוא 01 23 4C — 3 בייטים — וגם S9(5) נכנס ל-3 בייטים.
בהתאמת layout לקובץ חיצוני, בלי הטבלה הזו זזים בייט-בייט.
עוד הערה: DISPLAY לא אומר בהכרח מחרוזת ASCII.
ב-z/OS מניחים EBCDIC, אז גם אם הספרות נראות כתווים, ערכי הבייטים שונים מ-'0'–'9' ב-ASCII.6
5.4 REDEFINES / OCCURS / COPY / FILLER
ארבעת אלה הם המקומות שנתקעים בהם בקריאה.
REDEFINES
REDEFINES הוא מבט אחר על אותו אזור. זו לא copy.7
01 REC-BUF.
05 REC-TYPE PIC X.
05 REC-DATA PIC X(99).
01 HEADER-REC REDEFINES REC-BUF.
05 HDR-TYPE PIC X.
05 HDR-DATE PIC 9(8).
05 FILLER PIC X(91).
זה קרוב ל-union ב-C.
נפוץ בכתיבה של “100 בייטים אחד, שנקראים לפי סוג הרשומה”.
flowchart TB
accTitle: REDEFINES הוא פירוש אחר לאותו אזור
accDescr: REDEFINES אינו copy. זה מבט אחר על אותו זיכרון. אותו buffer נקרא גם כרשומה כללית וגם כ-header. כותבים צד אחד — גם המראה של הצד השני משתנה.
rd1["אזור זיכרון אחד"] --> rd2["נקרא כ-REC-BUF"]
rd1 --> rd3["נקרא כ-HEADER-REC"]
rd2 -.-> rd4["כותבים צד אחד, שני המראות משתנים"]
rd3 -.-> rd4
איור 10: שתי הגדרות, רצף בייטים אחד.
OCCURS
OCCURS הוא מערך. ב-COBOL קוראים לזה לרוב table.
05 WS-ITEM OCCURS 12 TIMES.
10 WS-PRICE PIC 9(5).
אם מופיע גם OCCURS DEPENDING ON, זו טבלה באורך משתנה.
זה יכול להזיז גם את מיקום השדות שאחריה. אם רצים עם ראש של אורך קבוע, יוצאים מה-offset.8
flowchart TB
accTitle: הזהירות ב-OCCURS DEPENDING ON
accDescr: OCCURS הוא מערך. עם DEPENDING ON זו טבלה באורך משתנה, וגם מיקום השדות שאחריה יכול לזוז לפי הערך. offset באורך קבוע מחטיא.
oc1["מצאנו OCCURS"] --> oc2{"יש DEPENDING ON?"}
oc2 -->|"אין"| oc3["טבלה במספר קבוע"]
oc2 -->|"יש"| oc4["טבלה באורך משתנה"]
oc4 -.-> oc5["גם מיקום השדות הבאים יכול לזוז"]
איור 11: שלוש המילים DEPENDING ON משנות את הנחת ה-offset.
COPY
COPY הוא include בזמן compile.
כלומר, הקובץ הפתוח כרגע עדיין לא בהכרח הצורה המלאה.9
COPY CUSTOMER-REC.
COPY ERROR-MAP.
די שגרתי שהגדרות records, דגלים משותפים, host variables ל-SQL וממשקים חיצוניים דחוסים ב-copybook.
כשיש הרבה COPY וקשה לקרוא, מהיר יותר לבדוק אם יש expanded source או compiler listing. ב-IBM Enterprise COBOL יש גם אפשרות MDECK שמוציאה את מקור הקלט אחרי עיבוד הספרייה.10
flowchart TB
accTitle: איך קוראים קוד עם COPY
accDescr: COPY הוא include בזמן compile, והקובץ הפתוח אולי לא שלם. בודקים copybook, ואם קשה — מחפשים expanded source, listing או פלט MDECK.
cy1["מצאנו COPY"] --> cy2["הקובץ הפתוח אולי לא שלם"]
cy2 --> cy3["פותחים copybook ובודקים"]
cy2 -.->|"כשקשה לקרוא"| cy4["מחפשים expanded source או listing"]
איור 12: מספר השורות שרואים עכשיו הוא לא בהכרח כל התכנית.
FILLER
FILLER הוא שדה בלי שם.
אבל “לא מתייחסים אליו” לא אומר שהוא חסר משמעות.
- אזור שמור
- חור לתאימות עם מפרט ישן
- יישור אורך רשומה
- רווח ל-
REDEFINES
כל אלה עובדים.
ל-FILLER אין שם, אבל יש לו אורך בבייטים. שוכחים את זה — והמיפוי לקובץ חיצוני זז בייט-בייט.
flowchart TB
accTitle: מה קורה כששוכחים לספור FILLER
accDescr: ל-FILLER אין שם אבל יש אורך. הוא משמש כאזור שמור או ליישור אורך רשומה. אם לא סופרים אותו, המיפוי לקובץ חיצוני זז בייט-בייט.
fl1["FILLER הוא שדה בלי שם"] --> fl2["אבל יש לו אורך בבייטים"]
fl2 --> fl3{"נכלל בחישוב ה-layout?"}
fl3 -->|"כן"| fl4["תואם לקובץ החיצוני"]
fl3 -->|"שכחנו"| fl5["זזים בייט-בייט"]
איור 13: גם לשדה שלא מתייחסים אליו יש תפקיד: אורך.
6. המינימום של PROCEDURE DIVISION
אם DATA DIVISION היא המפה, PROCEDURE DIVISION הוא מסלול התנועה.
6.1 PERFORM
PERFORM הוא מעבר הבקרה הבסיסי ב-COBOL.
בגדול: קוראים לעיבוד וחוזרים.11
הצורה הנפוצה:
PERFORM INIT-PROC
PERFORM UNTIL EOF
PERFORM READ-PROC
IF NOT EOF
PERFORM EDIT-PROC
PERFORM WRITE-PROC
END-IF
END-PERFORM
יש שני סוגים עיקריים:
- out-of-line
PERFORMשמצביע על פסקה או section - inline
PERFORM ... END-PERFORMעם בלוק במקום
בקוד ישן נפוץ גם טווח כמו PERFORM A-100 THRU A-199.
זה נוח, אבל אם מוסיפים פסקה באמצע קל למשוך אותה בטעות. בקריאה בודקים את סוף הטווח.
flowchart TB
accTitle: שלוש הצורות של PERFORM
accDescr: PERFORM יכול להיות out-of-line שקורא לפסקה וחוזר, inline עם בלוק במקום, או טווח עם THRU בקוד ישן. בטווח חובה לבדוק את הסוף, כי פסקה שנוספה באמצע נמשכת בקלות.
pf1["מצאנו PERFORM"] --> pf2["out-of-line שקורא לפסקה"]
pf1 --> pf3["inline במקום"]
pf1 --> pf4["טווח עם THRU"]
pf4 -.-> pf5["תמיד בודקים את סוף הטווח"]
איור 14: סוג ה-PERFORM קובע לאן חוזרים ומה הטווח.
6.2 IF / EVALUATE / scope
הסתעפות בסיסית היא IF.
EVALUATE קרוב ל-switch/case.
מה שצריך לשים לב אליו הוא איך נגמר ה-scope.12
END-IFEND-PERFORMEND-READ
קוד עם סיום מפורש כזה עדיין קריא.
הבעיה היא קוד ישן. ב-COBOL, . עובד כ-scope terminator משתמע, וסוגר בבת אחת משפטים שעדיין פתוחים.12
כלומר, נקודה אחת משנה:
- עד איפה ה-
IF - עד איפה ה-
PERFORM - איפה עוברים ל-sentence הבא
וגם NEXT SENTENCE אינו CONTINUE.
NEXT SENTENCE קופץ אחרי הנקודה הבאה, כך שהיעד תלוי במיקום ה-. שאחריו.12
בקוד COBOL ישן, מסתכלים על הנקודה, לא על סוף השורה.
flowchart TB
accTitle: המשקל של הנקודה
accDescr: קוד עם END-IF קריא. בקוד ישן הנקודה היא scope terminator משתמע שסוגר משפטים פתוחים, ונקודה אחת משנה את טווח IF ו-PERFORM.
sc1{"יש סיום מפורש?"}
sc1 -->|"יש END-IF ודומיו"| sc2["הטווח קריא"]
sc1 -->|"קוד ישן בלי"| sc3["הנקודה היא סיום משתמע"]
sc3 --> sc4["מיקום אחד משנה את הטווח"]
sc4 -.-> sc5["מסתכלים על הנקודה, לא על סוף השורה"]
איור 15: בזרימת הבקרה של קוד ישן, מיקום הנקודה מחזיק את המפתח.
6.3 READ / WRITE / CALL
ב-COBOL עסקי אלה חוזרים הרבה:
READWRITEREWRITESTARTCALL
במיוחד READ ... AT END ... הוא הקלאסיקה.
READ IN-FILE
AT END
SET EOF TO TRUE
NOT AT END
PERFORM PROCESS-REC
END-READ
אם יש CALL 'SUBPGM' USING ..., קופצים לתכנית אחרת.
אז פותחים את LINKAGE SECTION ו-PROCEDURE DIVISION USING של הנקרא — וצורת ההעברה נראית די ברור.
flowchart TB
accTitle: איך עוקבים אחרי CALL
accDescr: CALL קופץ לתכנית אחרת. פותחים LINKAGE SECTION ו-PROCEDURE DIVISION USING של הנקרא כדי לתפוס את צורת הארגומנטים.
ca1["מצאנו CALL"] --> ca2["קופצים לתכנית אחרת"]
ca2 --> ca3["פותחים LINKAGE SECTION של הנקרא"]
ca3 --> ca4["תופסים את צורת ההעברה דרך USING"]
איור 16: משמעות הקריאה נקראת יחד עם נקודת הכניסה של הנקרא.
7. מה שנמצא מחוץ ל-COBOL
ב-COBOL העולם לא תמיד נגמר בקוד.
- הגדרות קבצים
- סביבת הרצה
- חיבור ל-DB
- סביבת טרנזקציות
- בקרת job
כל אלה יושבים בחוץ.
לפחות אלה עוזרים לקרוא.
קבצים ו-FILE STATUS
FILE-CONTROL ב-ENVIRONMENT DIVISION ו-FILE SECTION / FD ב-DATA DIVISION נקראים כסט.13
SELECT IN-FILE ASSIGN TO ...
FILE STATUS IS WS-FS.
FD IN-FILE.
01 IN-REC.
05 ...
אם יש FILE STATUS, אחרי כל I/O נכנס קוד תוצאה.
בתקלות קבצים ובזיהוי EOF, בלי זה אין מאיפה להתחיל.14
flowchart TB
accTitle: הגדרת קובץ נקראת כסט
accDescr: SELECT ב-FILE-CONTROL ו-FD ב-FILE SECTION הם סט אחד. אם יש FILE STATUS, אחרי כל I/O נכנס קוד תוצאה — ומשם קוראים תקלות ו-EOF.
fs1["SELECT ב-FILE-CONTROL"] --> fs3["סט אחד של הגדרת קובץ"]
fs2["FD ב-FILE SECTION"] --> fs3
fs3 --> fs4["קוד תוצאה נכנס ל-FILE STATUS"]
fs4 -.-> fs5["נקודת הכניסה לתקלות ול-EOF"]
איור 17: צורת הקובץ כתובה בשני DIVISION.
EXEC SQL
אם זה מופיע, זה embedded SQL.
EXEC SQL
SELECT ...
END-EXEC.
כאן COBOL הוא “הכלי ל-host variables”, ותנאי השליפה או יעד העדכון יושבים בצד ה-SQL.
הקיצור: לקרוא את תוכן EXEC SQL כ-SQL רגיל.
EXEC CICS
אם זה מופיע, זה הקשר טרנזקציה של CICS.15
EXEC CICS
RECEIVE MAP(...)
END-EXEC.
ברגע הזה זו כבר לא קריאת batch רגילה. צריך מסך, טרנזקציה, קודי תשובה, COMMAREA — הקשר חיצוני.
JCL והגדרות הרצה
ב-mainframe batch, איזה dataset באמת משויך ו-באיזה סדר רץ ה-job לעיתים קרובות מחוץ לקוד COBOL. אם מהקוד לבד לא ברור “איפה הקובץ הזה”, זו לא בהכרח בעיה בקוד. פשוט עדיין לא מסתכלים על כל הטווח.
flowchart TB
accTitle: העולם שמחוץ לקוד
accDescr: EXEC SQL שם את תנאי השליפה בצד SQL, EXEC CICS שם מסך וטרנזקציה בהקשר חיצוני, וב-mainframe batch שיוך datasets וזרימת job יושבים ב-JCL.
ex1["EXEC SQL"] --> ex7["מסתכלים גם מחוץ לקוד"]
ex3["EXEC CICS"] --> ex7
ex5["JCL והגדרות הרצה"] --> ex7
ex7 -.-> ex2["תנאי SQL, הקשר מסך, זרימת job"]
איור 18: לפעמים לא מבינים כי הטווח צר, לא כי הקוד גרוע.
הבדלים בין compilers
המאמר כתוב עם IBM בראש, אבל בשטח פוגשים גם Micro Focus ו-COBOL על Linux / Windows. השלד משותף והקריאה לא משתנה, אבל יש נקודות קבועות שבהן אותה כתיבה נותנת תוצאה אחרת. כדאי לדעת אותן מראש.
| מה בודקים | z/OS (IBM Enterprise COBOL) | open systems (Micro Focus, Linux / Windows וכו’) |
|---|---|---|
| encoding | מניחים EBCDIC6 | מניחים ASCII6 |
| reference format | fixed הוא ברירת המחדל המסורתית. אפשר גם free1 | יש fixed ו-free, ברירת המחדל תלויה בהגדרת ה-build1 |
| איך מוצאים copybook | ציון ספרייה | נתיב חיפוש ב-compiler options |
| דיאלקט | — | יש אפשרות שמחליפה “לאיזה compiler מכוונים” |
מה שמשפיע במיוחד הוא encoding. גם באותו PIC X(10), קובץ שנכתב ב-z/OS ונקרא כמו שהוא ב-Windows נותן ערכי בייטים אחרים גם לספרות. הרבה מקרים של “העברנו והכול garbled” הם זה, וזה בעיה נפרדת מ-COMP-3.
עוד מקום שקל לראות בו הפרש בייצוג מספרי. ב-IBM Enterprise COBOL, BINARY / COMP-4 חותכים לפי מספר הספרות ב-PICTURE, ואילו COMP-5 מחזיק עד הקיבולת הבינארית הנייטיבית של 2 / 4 / 8 בייטים, והחיתוך קורה לפי גודל הבינארי.16 כלומר PIC S9(4) COMP ו-PIC S9(4) COMP-5 נראים דומה, אבל תקרת הערך שונה. אם בקוד שמחליף ערכים בינאריים עם מערכת אחרת מופיע COMP-5, קוראים את זה כ-כתוב כך בכוונה.
הקיצור כשמשווים לסביבה שלכם:
- קודם פותחים את הגדרת ה-build (makefile, JCL, הגדרות פרויקט). איזה compiler ובאילו options — זה לפני הקוד.
- מקבעים reference format (fixed / free). טעות כאן + עיצוב ב-editor = שבירה.
- מקבעים encoding. EBCDIC או ASCII משנים איך קוראים dump.
- מסמנים שדות COMP. כמעט כל הפרש compiler יושב כאן.
flowchart TB
accTitle: הקיצור כשמשווים לסביבה שלכם
accDescr: קודם פותחים הגדרת build כדי לדעת compiler ו-options, מקבעים fixed או free, מקבעים EBCDIC או ASCII, ומסמנים שדות COMP שבהם יוצא הפרש compiler.
ck1["קודם פותחים הגדרת build"] --> ck2["מקבעים reference format"]
ck2 --> ck3["מקבעים encoding"]
ck3 --> ck4["מסמנים שדות COMP"]
איור 19: ארבעה מהלכים לפני שקוראים את הקוד מונעים תאונות של הפרש compiler.
8. סדר קריאה מינימלי
כשנוחתים פתאום על COBOL, הסדר הבא בטוח יותר.
- לעבור על כל ה-
COPYאם אפשר לפתוח copybook — פותחים. אם לא — מחפשים listing או expanded source - לאסוף הגדרות records ברמה
01לרכז את הרמה העליונה ב-FILE SECTION,WORKING-STORAGE,LINKAGE SECTION - לקרוא
PICו-USAGEלזהות סכומים, תאריכים, מונים, קודים, דגלים - לחפש
READ/WRITE/REWRITE/CALL/EXEC SQL/EXEC CICSקודם תופסים I/O וגבול חיצוני - לעקוב רק אחרי המסלול הראשי הראשון
מתחילת
PROCEDURE DIVISIONלאורך שרשרתPERFORM - לראות
88ושדות status EOF, תקין/שגוי, קודי סוג נעשים קריאים - לסמן
REDEFINES/OCCURS DEPENDING ON/COMP-3אלה תמיד יחזרו, אז מסמנים אותם מראש כחומר מסוכן - אם זה קובץ — לראות
FILE STATUSזה מוריד הרבה קריאות שגויות של שגיאות I/O
בסדר הזה אין צורך לקרוא את כל הקובץ מההתחלה. ב-COBOL עדיף לתפוס קודם records, גבול חיצוני, מסלול ראשי, ורק אז לרדת לפרטים.
flowchart TB
accTitle: סדר קריאה בטוח
accDescr: עוברים על COPY ובודקים copybook, מרכזים רמה 01, קוראים צורה ב-PIC ו-USAGE, תופסים I/O וגבול חיצוני בחיפוש, עוקבים אחרי שרשרת PERFORM במסלול הראשי, ומסמנים חומר מסוכן.
ro1["עוברים על כל ה-COPY"] --> ro2["מרכזים רמה 01"]
ro2 --> ro3["קוראים צורה ב-PIC ו-USAGE"]
ro3 --> ro4["מחפשים I/O וגבול חיצוני"]
ro4 --> ro5["עוקבים אחרי שרשרת PERFORM במסלול הראשי"]
ro5 -.-> ro6["מסמנים חומר מסוכן"]
איור 20: לא קריאה צמודה של הכול, אלא חפירת החפיר בסדר הזה.
8.1 תרגול: לקרוא את הגדרת הרשומה הזו
הסבר לבד לא נדבק, אז שמים כאן record קטן. קודם עונים לבד, ואז מסתכלים על הפתרון למטה.
01 CUST-REC.
05 CUST-ID PIC X(8).
05 CUST-NAME PIC X(20).
05 CUST-KBN PIC X.
88 CUST-NORMAL VALUE '0'.
88 CUST-VIP VALUE '1'.
05 CUST-BALANCE PIC S9(7)V99 COMP-3.
05 CUST-HIST OCCURS 3 TIMES.
10 HIST-DATE PIC 9(8).
10 HIST-AMOUNT PIC S9(5)V99 COMP-3.
05 FILLER PIC X(4).
שאלות
- כמה בייטים יש ל-
CUST-RECכולו? - מאיזה בייט, מתחילת הרשומה, מתחיל
CUST-BALANCE? - מאיזה בייט מתחיל
HIST-AMOUNTשל הפריט השני? - כש-
CUST-KBNמכיל'1', איזה condition-name true? - אם פותחים את הקובץ הזה ב-editor טקסט, אילו שדות נראים שבורים?
- ציינו שני דברים שההגדרה הזו לבדה לא אומרת.
תשובות
-
74 בייטים. הפירוק:
שדה חישוב בייטים CUST-IDX(8)8 CUST-NAMEX(20)20 CUST-KBNX1 CUST-BALANCECOMP-3 של 9 ספרות 5 CUST-HIST(8 + 4)× 336 FILLERX(4)4 סה”כ 74 רמה
88היא condition-name ולכן לא צורכת בייטים. לספור אותה זו טעות נפוצה. ל-FILLERאין שם, אבל 4 הבייטים קיימים לגמרי. -
בייט 30. לפניו יש
8 + 20 + 1 = 29בייטים, והוא מתחיל אחריהם. -
בייט 55.
CUST-HISTמתחיל בבייט 35, כל פריט 12 בייטים, אז פריט 1 הוא 35–46, פריט 2 הוא 47–58. 8 הבייטים הראשונים הםHIST-DATE, לכןHIST-AMOUNTמתחיל בבייט 55. -
CUST-VIP. אין אזור נפרד בשםCUST-VIP. כש-CUST-KBNהוא'1', אפשר לקרוא לזה בשם הזה. -
CUST-BALANCEו-HIST-AMOUNT. שניהםCOMP-3, אז כטקסט זה רצף חסר משמעות.HIST-DATEהואPIC 9(8)ב-DISPLAY, אז בסביבת ASCII אפשר לקרוא אותו כספרות כמו20260317. ב-EBCDIC הספרות נראות כספרות, אבל ערכי הבייטים שונים מ-ASCII. -
למשל:
- האם ההגדרה עצמה הגיעה ב-
COPY. בלי לראות את ה-copybook לא יודעים אם זו הגרסה שבאמת בשימוש. - האם encoding של הקובץ הוא EBCDIC או ASCII. זה משנה איך נראים
PIC Xו-PIC 9 DISPLAY. - האם ב-production נכנס ל-
CUST-KBNמשהו מלבד'0'ו-'1'. יש רק שני condition-names, וזה לא ערובה שלא יגיעו ערכים אחרים. - מאפייני הקובץ עצמו (אורך רשומה, קבוע/משתנה,
FILE STATUS). זה לא נראה בליENVIRONMENT DIVISIONו-FD.
- האם ההגדרה עצמה הגיעה ב-
אם טעיתם בשאלות 1 ו-3, חוזרים לטבלת הספרות והבייטים ב-5.3. רוב קריאות הלא-נכון ב-COBOL מתחילות כאן.
9. איפה נתקעים הרבה
לבסוף, המקומות שמתחילים נתקעים בהם בהסתברות גבוהה.
לחשוב ש-REDEFINES הוא “משתנה אחר”
לא. קוראים את אותו אזור בצורה אחרת. כותבים צד אחד — גם המראה של הצד השני משתנה.7
לחשוב ש-88 הוא “bool עצמאי”
לא.
זה רק שם לערך של השדה שמעליו. SET WS-OK TO TRUE שם מאחורי הקלעים את הערך המתאים בשדה הבסיס.3
להתעלם מ-COPY ולקרוא רק את גוף הקובץ
הקובץ הפתוח הוא עדיין חצי מהתמונה. הגדרות שדות, דגלים משותפים ו-host variables יושבים בחוץ די שגרתית.9
לחשוב ש-MOVE הוא השמה פשוטה
MOVE אינו סתם memcpy.
לפי טיפוס הצד המקבל יכולות לקרות המרה, יישור ספרות, מילוי אפסים, קיטום, עריכה או ביטול עריכה.17
לזלזל ב-.
ה-. ב-COBOL כבד יותר משנדמה.
בקוד ישן בלי סיום מפורש, אם טועים ב-עד איפה הנקודה הזו סוגרת, קוראים לא נכון את זרימת הבקרה.12
לחשוב ש-packed decimal או EBCDIC הם “garbled”
זה לא בהכרח שבור. לפעמים זה פשוט לא מחרוזת מלכתחילה, או שזה לא ASCII.46
לחשוב שמה שאחרי OCCURS DEPENDING ON יושב במיקום קבוע
השדות אחרי טבלה באורך משתנה יכולים לזוז לפי הערך. עם ראש של אורך קבוע, כל חישוב ה-offset זז.8
10. טבלת עזר מהירה
| מילה שמצאנו | מה בודקים קודם |
|---|---|
01 |
הרמה העליונה של record או קבוצה. מכאן תופסים את התמונה |
88 |
שם משמעות לדגל או לקוד מצב. מפתח להסתעפות |
PIC X(...) |
שדה תווים |
PIC 9(...) / S9(...)V... |
שדה מספרי. בודקים מספר ספרות ומיקום עשרוני |
COMP |
binary |
COMP-3 |
packed decimal. סיכוי גבוה לסכום או מונה |
REDEFINES |
פירוש אחר לאותו אזור |
OCCURS |
מערך / table |
OCCURS DEPENDING ON |
אורך משתנה. שימו לב גם למיקום הבא |
FILLER |
אין שם, אבל יש אורך |
COPY |
בלי copybook אין צורה מלאה |
PERFORM |
שלד המסלול הראשי |
READ / WRITE / REWRITE |
I/O לקובץ |
EXEC SQL |
עיבוד DB |
EXEC CICS |
עיבוד טרנזקציה |
FILE STATUS |
קוד תוצאה של I/O |
11. סיכום
COBOL לא קשה כי היא ישנה. הגדרת נתונים, קובץ חיצוני והקשר הרצה קשורים חזק, ולכן רק הכניסה הראשונה קשה לראות.
הסט המינימלי לקריאה, שוב:
- תופסים מפה עם
DIVISION - קוראים קודם
DATA DIVISION - קוראים צורת שדה עם
PICו-USAGE - מסמנים
COMP-3,REDEFINES,OCCURS,88,COPY - עוקבים אחרי
PERFORM,READ,WRITE,CALL - תופסים גבול חיצוני עם
FILE STATUS,EXEC SQL,EXEC CICS - לא מזלזלים באיך ה-
.עובד
ברגע שזה נראה, COBOL עוברת מ”קסם עתיק” ל”שפת עיבוד records”. legacy לא מפחיד כי השם ישן. הוא מפחיד כש-טועים בקנה המידה הראשון. אם קנה המידה של המפה מתאים, זה נקרא די רגיל.
flowchart TB
accTitle: קוראים בקנה מידה מתאים
accDescr: תופסים מפה עם DIVISION, קוראים קודם DATA DIVISION ותופסים צורה, עוקבים אחרי הזרימה עם PERFORM ו-I/O, ותופסים גבול חיצוני עם FILE STATUS, EXEC SQL ו-EXEC CICS. אז COBOL נקראת כשפת עיבוד records.
sm1["תופסים מפה עם DIVISION"] --> sm2["קוראים צורה ב-DATA DIVISION"]
sm2 --> sm3["עוקבים אחרי הזרימה עם PERFORM ו-I/O"]
sm3 --> sm4["תופסים גבול חיצוני"]
sm4 -.-> sm5["הקסם העתיק הופך לשפת עיבוד records"]
איור 21: הקושי הוא לא גיל השפה. הוא בחירת קנה המידה הראשון.
12. מקורות
אלה המקורות העיקריים בגוף המאמר. המספרים בגוף הם קישורים לרשימה הזו, ומהחץ בסוף כל פריט אפשר לחזור למקום המקורי.
-
IBM, “Reference format” / IBM, “Area A or Area B” / Micro Focus, “Fixed Format” ↩ ↩2 ↩3 ↩4
-
IBM, “Level-numbers” ↩ ↩2
-
IBM, “Format 2: condition-name value” ↩ ↩2
-
IBM, “Examples: numeric data and internal representation” ↩ ↩2 ↩3 ↩4
-
IBM, “PACKED-DECIMAL (COMP-3)” ↩ ↩2
-
IBM, “The EBCDIC character set” / IBM, “Handling differences in ASCII SBCS and EBCDIC SBCS characters” ↩ ↩2 ↩3 ↩4 ↩5
-
IBM, “REDEFINES 節” ↩ ↩2
-
IBM, “OCCURS DEPENDING ON clause” ↩ ↩2
-
IBM, “COPY ステートメント” ↩ ↩2
-
IBM, “PERFORM statement” / IBM, “Procedure division structure” ↩
-
IBM, “Scope terminators” / IBM, “Coding a choice of actions” ↩ ↩2 ↩3 ↩4
-
IBM, “ファイル構造の詳細記述” ↩
-
IBM, “FILE STATUS clause” / IBM, “Using file status keys” ↩
-
IBM, “Computational items” ↩
-
IBM, “Elementary move rules” ↩
מאמרים קשורים
מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.
אסור להשתמש בערך שפוענח מקוד QR כמו שהוא — תיקון שגיאות שהצליח אינו מבטיח את הערך
תיקון שגיאות בקוד QR אינו מבטיח שהערך שפוענח נכון. דוגמאות אמיתיות ושני מפענחים שונים מראים כיצד לכלוך יכול להחזיר ערך אחר, ומה מערכת עסק...
מה זה Reg-Free COM: COM בלי רישום ב-registry
יסודות Reg-Free COM: תפקיד ה-activation context וה-manifest, היתרונות, המגבלות, ואיך מחליטים בפועל.
COM, ActiveX ו-OCX — ההבדלים והקשר ביניהם
מהו COM, מהו ActiveX ומהו OCX — סקירה מעשית של ההבדלים והקשר ביניהם, הזיקה ל-OLE, איפה זה בשימוש, ואיך כדאי להתייחס לזה היום.
לבנות כלי ניתוח ל-PowerShell בתוך PowerShell — לקרוא סקריפטים עם AST, לא עם ביטויים רגולריים
להציג AST אמיתי של PowerShell ולראות לאיזה אובייקט הופכת כל שורת קוד. לעבור מ-ScriptBlockAst ל-CommandAst ולמצוא היכן נקרא Write-Host, בל...
איך קיצור דרך ב-Windows מוצא קובץ שהעברתם? — המיקום של הקובץ והזהות שלו הם שני דברים שונים
העברתם את הקובץ המקורי, ובכל זאת הקיצור פותח אותו. Windows מחפש את היעד לא רק לפי הנתיב השמור, אלא גם לפי מזהי מעקב ומאפיינים של הקובץ, ו...
נושאים קשורים
העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.
נושאים טכניים ב-Windows
שער לנושאי פיתוח Windows, חקירת תקלות וניצול נכסים קיימים.
שירותים הקשורים לנושא הזה
המאמר קשור ישירות לשירותים הבאים.
ייעוץ טכני וסקירת תכנון
איך קוראים COBOL קיים, מאיפה נכנסים לשינוי, איך תופסים גבולות חיצוניים, ואיך מעריכים לפני מעבר — מתאים לייעוץ טכני ול-design review.
חקירת תקלות ואיתור גורמים
תקלה מיד אחרי handover, או מעקב אחרי אי-עקביות בנכסי COBOL — עבודה שקל לקחת כחקירת תקלה.
שאלות נפוצות
שאלות נפוצות בפניות בנושא המאמר.
- מאיפה מתחילים לקרוא קוד COBOL?
- PROCEDURE DIVISION לבד נותן רק חצי מהתמונה. COBOL היא קודם כל שפת הגדרת records, ורק אחר כך שפת לוגיקה — לכן קודם פותחים DATA DIVISION. סדר בטוח: לעבור על כל ה-COPY ולבדוק copybooks, לרכז את הגדרות הרשומה ברמה 01, לקרוא את צורת השדות דרך PIC ו-USAGE, לחפש READ, WRITE, CALL, EXEC SQL, EXEC CICS כדי לתפוס I/O וגבול חיצוני, ורק אז לעקוב אחרי שרשרת PERFORM בתחילת PROCEDURE DIVISION כדי לתפוס את המסלול הראשי.
- מה אומר PIC S9(7)V99 COMP-3?
- PIC מתאר את צורת השדה, USAGE מתאר באיזה ייצוג הוא נשמר. S9(7)V99 הוא מספר עם סימן, 7 ספרות שלמות ועוד 2 עשרוניות, אבל V הוא נקודה עשרונית לוגית בלבד — אין תו נקודה בנתונים. COMP-3 הוא packed decimal, ונפוץ בסכומים, מסים, מונים ותעריפים. כטקסט זה נראה שבור, וזה צפוי. dump בתחושה של CSV או UTF-8 הוא מתכון לתאונה.
- איך מבינים רמה 88 ו-REDEFINES?
- רמה 88 אינה משתנה bool עצמאי. זה condition-name — שם שנתנו לערך של השדה שמעליו. SET WS-OK TO TRUE שם מאחורי הקלעים את הערך המתאים בשדה הבסיס. REDEFINES הוא מבט אחר על אותו שטח זיכרון, לא copy. זה קרוב ל-union ב-C. כותבים צד אחד — גם המראה של הצד השני משתנה. נפוץ כשמזהים את אותו buffer לפי סוג רשומה.
- מה עושים כשיש הרבה COPY ולא רואים את התמונה?
- COPY הוא include בזמן compile, כך שהקובץ הפתוח כרגע עדיין לא בהכרח הצורה המלאה. די שגרתי שהגדרות רשומה, דגלים משותפים, host variables ל-SQL וממשקים חיצוניים יושבים ב-copybook. כשקשה לקרוא, מהיר יותר לבדוק אם יש expanded source או compiler listing. ב-IBM Enterprise COBOL יש גם אפשרות MDECK שמוציאה את מקור הקלט אחרי עיבוד הספרייה.