ما يجب أن تعرفه قبل قراءة مصدر COBOL
· آخر تحديث: · 小村 豪 · COBOL, تقنيات قديمة, أنظمة الأعمال, الصيانة, Mainframe
سجل التعديلات (4 تحديثات، آخر تحديث 3 Sep، 2026)
سجل بالتغييرات التي أُجريت على هذا المقال. وحيثما حُفظت نسخة سابقة، تبقى متاحة للقراءة عبر رابط دائم يحمل معرّف DOI.
- أُضيفت روابط الاستشارة الموجودة في الأصل الياباني (consultation_services). ولم يتغيّر نصّ المقالة نفسه. قراءة النسخة السابقة لهذا التحديث (DOI: 10.5281/zenodo.22240860)
- أُعيدَت الترجمة العربية كترجمة كاملة عن النص الياباني الأصلي، وأُضيفَت خريطة المعرفة.
- تُرجمت تعليقات تخطيط بايتات COMP-3 (packed decimal) من اليابانية إلى العربية.
- أعيدت الترجمة كترجمة كاملة عن النص الياباني الأصلي. كانت النسخة العربية السابقة مختصراً يسقط أبواباً وجداول ورسوم Mermaid وتعليقات الأشكال وFAQ. أُعيدت هذه العناصر وفق الأصل الياباني، والادّعاءات التقنية مطابقة للنسخة اليابانية.
- النشر الأول
الاستشهاد بهذا المقال(DOI: 10.5281/zenodo.21621408)
هذا المقال محفوظ على Zenodo. يرد أدناه معرّف DOI الذي يشير دائمًا إلى أحدث نسخة، ومعرّف DOI المثبَّت على النسخة التي تقرؤها.
小村 豪 (2026). ما يجب أن تعرفه قبل قراءة مصدر COBOL. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621408 https://comcomponent.com/ar/blog/2026/03/17/001-cobol-minimum-reading-guide/
- DOI (أحدث نسخة)
- 10.5281/zenodo.21621408
- DOI (هذه النسخة)
- 10.5281/zenodo.22279829
التسليم، الاستجابة للأعطال، صيانة حزمة من بائع. في مثل هذه المواقف قد يأتي يوم يطير فيه مصدر COBOL نحوك فجأة.
- اسم الملف
.cblأو.cpy - أسماء المتغيّرات كلّها بأحرف كبيرة
01و05و77و88تتراصف- تظهر عبارات مثل
PIC S9(7)V99 COMP-3تبدو شيئاً بين تعويذة وبرنامج محاسبي - وفوق ذلك
COPYفي كل مكان، ولا تُرى الصورة كاملة من الملف المفتوح وحده
عند هذه النقطة تتوقف يد معظم الناس لحظة.
غير أن خريطة القراءة ليست بهذا الحجم. لـ COBOL فروق بحسب المعالج والمنتج، لكن الهيكل الذي ينبغي تثبيته أولاً عند قراءة نظام أعمال قائم مشترك إلى حد بعيد. نأخذ هنا عوائل IBM وCOBOL الأعمال النموذجي، ونرتّب الحدّ الأدنى لمن وجد نفسه فجأة أمام قراءة المصدر.
flowchart TB
accTitle: لماذا تتوقف اليد وحجم الخريطة
accDescr: يبين المخطّط أن الأسماء بالأحرف الكبيرة وأرقام المستويات وعبارات مثل PIC S9(7)V99 COMP-3 وكثرة COPY التي تخفي الصورة الكاملة توقف اليد، لكن الهيكل اللازم لقراءة نظام أعمال قائم مشترك عبر المعالجات والخريطة ليست كبيرة إلى ذلك الحد.
iv1["تتوقف اليد أمام عبارات غير مألوفة"] --> iv2["لكن الهيكل مشترك عبر المعالجات"]
iv2 --> iv3["امسك أولاً خريطة الحدّ الأدنى"]
iv1 -.-> iv4["COPY في كل مكان فلا تُرى الصورة كاملة"]
الشكل 1: ما يبدو تعويذة يُختصر إلى بضعة مفاهيم مشتركة.
1. الخلاصة أولاً (بكلمة)
إن قلناها بخشونة مفيدة عملياً، فهي كالتالي.
- COBOL قبل أن يكون لغة منطق هو بقوة لغة تعريف سجلات
- قراءة
PROCEDURE DIVISIONوحدها لا تعطيك إلا نصف الصورة. انظر أولاً إلىDATA DIVISION PICهو شكل العنصر، وUSAGEهو بأي تمثيل يُحفظCOMP-3هو packed decimal. يظهر كثيراً في عالم المبالغ والعدادات88ليس متغيّراً منفصلاً بقدر ما هو اسم شرط أُعطي لقيمة العنصر السابقREDEFINESآلية لـ رؤية الذاكرة نفسها بشكل آخر. ليست نسخاً- إن وُجد
COPYفالمصدر المفتوح أمامك لم يكتمل بعد. بلا copybook لا تُرى الصورة كاملة - إن تبعت
PERFORMوIFوEVALUATEوREADوWRITEوCALLأمسكت بالتدفّق العام تقريباً - المصدر القديم تنسيق ثابت لموقع العمود فيه معنى. الفراغ الظاهر ليس زينة1
باختصار، DIVISION وPIC وUSAGE وCOMP-3 وREDEFINES وOCCURS و88 وCOPY وPERFORM. إن أمكن قراءة هذه انخفض معدّل الضياع كثيراً.
في المخطّط، يشير الخطّ المتّصل إلى علاقة قائمة دائماً، ويشير الخطّ المتقطّع إلى علاقة مشروطة (شروط قيامها مذكورة في شرح كلّ علاقة في الصفحة التفصيليّة). القائمة الكاملة للعلاقات (المجموع 21، مع الأدلّة ودرجة اليقين) وتعريفات المفاهيم الرئيسة مجمّعة في صفحة تفاصيل خريطة المعرفة (باليابانية). البيانات: JSON-LD / Turtle
2. COBOL أولاً لغة «شكل البيانات»
إن قرأت بشعور C# أو Java رغبت أولاً في تتبع if وfor واستدعاء الدوال.
لكن COBOL أسرع إن ثبّت قبل ذلك «أي سجل يستقبل هذا البرنامج، وأي سجل يصنع، وأي مخزن يملك».
COBOL الأعمال النموذجي يسير تقريباً كالتالي.
- يقرأ سجلاً من ملف أو قاعدة بيانات
- يضعه في عناصر على
WORKING-STORAGE - يتفرّع حسب الشرط
- يعيد حزمه في سجل آخر
- يكتب
أي أن التخطيط يقف قبل الخوارزمية في الغالب.
flowchart TB
accTitle: تدفّق COBOL الأعمال النموذجي
accDescr: مخطّط لتدفّق COBOL الأعمال النموذجي: قراءة سجل من ملف أو قاعدة بيانات، وضعه في عناصر WORKING-STORAGE، التفرّع حسب الشرط، إعادة الحزم في سجل آخر، ثم الكتابة.
f1["اقرأ السجل"] --> f2["ضعه في WORKING-STORAGE"]
f2 --> f3["تفرّع حسب الشرط"]
f3 --> f4["أعد الحزم في سجل آخر"]
f4 --> f5["اكتب"]
الشكل 2: البطل تدفّق السجلات، والخوارزمية تنحشر بينهما.
مثال الهيكل كالتالي.
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.
عند قراءة هذه الشيفرة ينبغي النظر أولاً إلى نوع SALE-AMOUNT ومعنى EOF قبل PERFORM.
COBOL يهدأ فجأة إن قُرئ بهذا الترتيب.
3. انظر أولاً إلى الـ DIVISION الأربعة
ينقسم مصدر COBOL أولاً إلى أربعة DIVISION كبيرة.
| DIVISION | ما تنظر إليه أولاً |
|---|---|
IDENTIFICATION DIVISION |
اسم البرنامج، تعليقات قديمة، المنشأ |
ENVIRONMENT DIVISION |
الملفات، الموارد الخارجية، افتراضات الإدخال/الإخراج |
DATA DIVISION |
تعريفات السجلات، منطقة العمل، الوسائط |
PROCEDURE DIVISION |
خطوات المعالجة الفعلية |
ما يهم خصوصاً هذا الجانب.
FILE SECTIONفيه تعريف سجل ملف الإدخال/الإخراجWORKING-STORAGE SECTIONفيه المتغيّرات والأعلام والعدادات ومخازن العمل المعتادةLOCAL-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. لا تفزع من مظهر التنسيق الثابت
في COBOL القديم موقع العمود نفسه في سطر المصدر له معنى. إن نظرت دون معرفة ذلك بقي «لماذا هذا الفراغ الغريب على اليسار» لغزاً أبدياً. 1
في التنسيق الثابت الصورة التقريبية كالتالي.
- الأعمدة 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 فصاعداً. قد يستخدمه بعض المعالجات حقلاً تعريفياً، لكنه لا يدخل في معنى البرنامج
إن أسقطنا ذلك على مصدر فعلي صار كالتالي.
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في المثال كذلك، وهو تتمة حرفية السلسلة في السطر السابق. - الأعمدة 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.
الفراغ هنا ليس «تنسيقاً» بالمعنى الحديث، بل نحو جزئياً. تحويل علامات الجدولة في المحرّر، أو الإزاحة إلى اليسار، أو النسخ واللصق بلا عناية يكسر الشيفرة عادة. عند النظر إلى مصدر قديم اشك أولاً إن كان الملف fixed format أم free format. تطبيق تنسيق تلقائي حديث على مصدر بالصيغة الثابتة يكسر حد Area A وArea B فلا تمرّ الترجمة.
flowchart TB
accTitle: قبل لمس مصدر بالتنسيق الثابت
accDescr: يبين المخطّط أنه في المصدر القديم يُؤكَّد أولاً إن كان fixed format أم free format، وأن تطبيق تنسيق تلقائي حديث أو تحويل علامات الجدولة على مصدر ثابت يكسر حد Area A وArea B فلا تمرّ الترجمة.
fx1["فُتح مصدر قديم"] --> fx2{"fixed أم free؟"}
fx2 -->|"صيغة ثابتة"| fx3["موقع العمود نفسه نحو"]
fx3 -.-> fx4["التنسيق التلقائي وتحويل الجدولة يكسرانه"]
fx2 -->|"صيغة حرّة"| 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-OK عندما يكون WS-STATUS هو '0'.
flowchart TB
accTitle: حقيقة المستوى 88
accDescr: يبين المخطّط أن المستوى 88 ليس متغيّر bool مستقلّاً بل اسم شرط أُعطي لقيمة العنصر السابق، وأن WS-OK يصبح صادقاً بذلك الاسم عندما تكون قيمة WS-STATUS معيّنة فقط.
cn1["العنصر الأساس WS-STATUS"] --> cn2{"ما القيمة؟"}
cn2 -->|"عندما تكون 0"| cn3["يصدق بالاسم WS-OK"]
cn2 -->|"عندما تكون 9"| cn4["يصدق بالاسم 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 أرقام صحيحة + رقمين عشريين |
مثلاً:
PIC X(10)→ 10 أحرفPIC 9(5)V99→ 5 أرقام صحيحة + رقمين عشريينPIC S9(7)V99→ 7 أرقام صحيحة موقّعة + رقمين عشريين
هنا V مهم خصوصاً.
V لا يحمل حرف . فعلياً.
PIC 9(5)V99 يُعامل «عدداً بفاصلة عشرية من رقمين»، لكن حرف النقطة لا يدخل في البيانات.
لذا تفسير الملف أو التفريغ «كنص ظاهري» يسقط في الغالب.
flowchart TB
accTitle: V فاصلة عشرية منطقية
accDescr: يبين المخطّط أن V في PIC 9(5)V99 فاصلة عشرية منطقية ولا تحمل حرف نقطة فعلياً ولا تدخل نقطة في البيانات، لذا يسقط التفسير كنص ظاهري للملف أو التفريغ.
vd1["PIC 9(5)V99"] --> vd2["يُعامل عدداً بفاصلة من رقمين"]
vd2 --> vd3["لا يدخل حرف نقطة في البيانات"]
vd3 -.-> vd4["التفسير كنص ظاهري يسقط"]
الشكل 6: الفاصلة العشرية في التعريف فقط، لا في البيانات.
5.3 USAGE / DISPLAY / COMP / COMP-3
إن كان PIC الشكل، فـ USAGE هو بأي تمثيل يُحفظ.
يكفي تثبيت التالي لتقرأ كثيراً. 45
| الرمز | المعنى التقريبي | ما تنتبه إليه عند القراءة |
|---|---|---|
DISPLAY |
عشري خارجي يُرى كحروف | على الحاسب المركزي قد يُفترض EBCDIC 6 |
COMP / BINARY |
ثنائي | عدد الأرقام الظاهر والتمثيل الداخلي أمران مختلفان |
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: يبين المخطّط أن العنصر العددي الموقّع نفسه يختلف حمل محتواه بحسب USAGE: DISPLAY عشري خارجي يُرى كحروف، وCOMP ثنائي، وCOMP-3 packed decimal.
us1["عنصر رقمي بالشكل نفسه"] --> us2["DISPLAY (يُرى كحروف)"]
us1 --> us3["COMP (ثنائي)"]
us1 --> us4["COMP-3 (packed decimal)"]
us4 -.-> us5["يبدو مكسوراً إن قُرئ كنص"]
الشكل 7: حتى إن تطابق PIC، يتغيّر تسلسل البايتات إن تغيّر USAGE.
عملياً الأهم ردّ الفعل لحظة رؤية COMP-3.
- إنه packed decimal
- غالباً مبلغ أو ضريبة أو عدّاد أو معدّل
- رؤيته كنص تجعله يبدو مكسوراً وهذا متوقّع
- النظر إليه بمزاج CSV أو UTF-8 يوقع حوادث
إن حملت هذا الفهم لم تُذعر بلا طائل من مظهر التفريغ أو الملف الثنائي.
flowchart TB
accTitle: ردّ الفعل لحظة رؤية COMP-3
accDescr: يبين المخطّط ردّ الفعل المطلوب عند رؤية COMP-3: إدراك أنه packed decimal، والشك في بنود المبالغ أو الضرائب أو العدادات أو المعدّلات، وعدم الذعر إن بدا مكسوراً كنص، وتجنّب النظر بمزاج CSV أو UTF-8.
cp1["وجدت COMP-3"] --> cp2["تدرك أنه packed decimal"]
cp2 --> cp3["تشك في بند مبلغ أو عدّاد"]
cp3 --> cp4["لا تذعر إن بدا مكسوراً كنص"]
الشكل 8: هذا المنعكس وحده يقلّل مرات الذعر أمام التفريغ.
أي تسلسل بايتات يصير COMP-3 فعلاً
تتبع هذا باليد مرّة واحدة يغيّر ما تراه بعد ذلك.
لقواعد 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 أربعة أرقام، فبسبب القاعدة 2 يُفتح فراغ رقم واحد في المقدّمة. ذلك هو 0 الأوّل.
بالطريقة نفسها نتتبع PIC S9(7)V99 COMP-3 الذي تكرّر في هذه المقالة.
S9(7)V99هو 7 أرقام صحيحة + رقمين عشريين = 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 لا يظهر في أي موضع.
هذا هو معنى «يبدو تشويهاً لكنه غير مكسور». إن فتحت تفريغاً وصادفت تسلسلاً بلا معنى، اشك أولاً إن كان 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["يبدو تشويهاً لكنه غير مكسور"]
الشكل 9: قاعدتا الحزم تحوّلان التفريغ المبهم إلى عمود قابل للقراءة.
بالمناسبة نضع جدولاً سريعاً من عدد الأرقام إلى عدد البايتات. عدد البايتات يُحسب بـ «اقسم عدد التسعات على 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 |
ظهور عددَي أرقام للبايت نفسه لأن فراغ رقم واحد يُفتح في المقدّمة عندما يكون عدد التسعات زوجياً فقط. لذلك يصير S9(4) ثلاثة بايتات 01 23 4C، ويسع S9(5) أيضاً ثلاثة بايتات.
عند مطابقة التخطيط مع ملف خارجي، بلا هذا الجدول ينزاح العالم بايتاً بايتاً.
تكميل واحد: DISPLAY لا يعني حتماً سلسلة ASCII.
على أنظمة z/OS يُفترض EBCDIC، لذا حتى إن بدت الأرقام حروفاً فقد تختلف قيمة البايت عن '0' - '9' في ASCII. 6
5.4 REDEFINES / OCCURS / COPY / FILLER
هذه الأربعة مطبات عند القراءة.
REDEFINES
REDEFINES آلية لـ رؤية المنطقة نفسها بشكل آخر. ليست نسخاً. 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 ليست نسخاً بل آلية لرؤية منطقة الذاكرة نفسها بشكل آخر، فيُقرأ المخزن نفسه سجلاً عاماً أو سجل ترويسة، وكتابة أحد الجانبين تغيّر مظهر الآخر أيضاً.
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 فهو جدول متغيّر الطول.
قد يؤثّر حتى في موضع العناصر اللاحقة، فتتبعه بمزاج الطول الثابت يُسقط القدم. 8
flowchart TB
accTitle: الانتباه إلى OCCURS DEPENDING ON
accDescr: يبين المخطّط أن OCCURS مصفوفة، وأن إلحاق OCCURS DEPENDING ON يجعله جدولاً متغيّر الطول قد يتحرّك معه موضع العناصر اللاحقة بحسب القيمة، فتتبع الإزاحة بمزاج الطول الثابت يُسقط القدم.
oc1["وجدت OCCURS"] --> oc2{"هل أُلحق DEPENDING ON؟"}
oc2 -->|"لا"| oc3["جدول بعدد ثابت"]
oc2 -->|"نعم"| oc4["جدول متغيّر الطول"]
oc4 -.-> oc5["قد يتحرّك موضع العناصر اللاحقة أيضاً"]
الشكل 11: ثلاث كلمات DEPENDING ON تغيّر افتراض حساب الإزاحة.
COPY
COPY هو include وقت الترجمة.
أي قد لا يكون المصدر المفتوح أمامك الشكل المكتمل بعد. 9
COPY CUSTOMER-REC.
COPY ERROR-MAP.
دفع تعريفات السجلات والأعلام المشتركة وhost variable لـ SQL والواجهات الخارجية إلى copybook أمر شائع جداً.
إن كثرت COPY وصعبت القراءة، فأسرع أن تتحقق إن كان بإمكانك رؤية المصدر بعد التوسيع أو compiler listing. في IBM Enterprise COBOL خيار MDECK يكتب مصدر الإدخال بعد معالجة المكتبات. 10
flowchart TB
accTitle: كيف تقرأ مصدراً فيه COPY
accDescr: يبين المخطّط أن COPY هو include وقت الترجمة وقد لا يكون المصدر المفتوح الشكل المكتمل، لذا تُفتح copybook للتحقق، وإن صعبت القراءة يُبحث عن المصدر بعد التوسيع أو compiler listing أو خرج خيار MDECK.
cy1["وجدت COPY"] --> cy2["قد يكون المصدر المفتوح غير مكتمل"]
cy2 --> cy3["افتح copybook وتحقق"]
cy2 -.->|"إن صعبت القراءة"| cy4["ابحث عن المصدر بعد التوسيع أو listing"]
الشكل 12: عدد الأسطر التي تراها الآن ليس بالضرورة البرنامج كلّه.
FILLER
FILLER عنصر بلا اسم.
غير أنه ليس «بلا معنى لأنه غير مُشار إليه».
- منطقة محجوزة
- ثقب للتوافق مع مواصفة قديمة
- مواءمة طول السجل
- فراغ لـ
REDEFINES
يؤثّر عادة بهذه الصفات.
FILLER بلا اسم فقط، وهو موجود كعدد بايتات. نسيان ذلك يزيح عالم المطابقة مع الملف الخارجي بايتاً بايتاً.
flowchart TB
accTitle: ماذا يحدث إن نسيت عدّ FILLER
accDescr: يبين المخطّط أن FILLER بلا اسم فقط وهو موجود كعدد بايتات ويعمل منطقة محجوزة أو مواءمة لطول السجل، فإن نُسي عدّه انزاحت المطابقة مع الملف الخارجي بايتاً بايتاً.
fl1["FILLER عنصر بلا اسم"] --> fl2["موجود كعدد بايتات"]
fl2 --> fl3{"هل أُدخل في حساب التخطيط؟"}
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
لـ PERFORM سلالتان كبيرتان.
- out-of-line
PERFORMيحدّد فقرة أو قسماً - 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 / النطاق
التفرّع الشرطي أساسه IF.
EVALUATE يكفي تصوّره شيئاً مثل switch/case.
ما ينبغي الانتباه إليه هو كيف ينتهي النطاق. 12
الشيفرة ذات النهاية الصريحة مثل:
END-IFEND-PERFORMEND-READ
لا تزال أسهل قراءة.
المشكلة في الشيفرة القديمة. في COBOL يعمل . منهي نطاق ضمنياً، فيغلق الجمل التي لم تُغلق بعد دفعة واحدة. 12
أي بنقطة واحدة يتغيّر:
- إلى أين يمتد
IF - إلى أين يمتد
PERFORM - أين ينتقل إلى الجملة التالية (sentence)
ثم NEXT SENTENCE ليس هو CONTINUE.
NEXT SENTENCE يتقدّم إلى ما بعد النقطة التالية، فموضع . اللاحق يغيّر وجهة القفز. 12
عند قراءة COBOL قديم يكفي تقريباً النظر إلى النقطة لا إلى نهاية السطر.
flowchart TB
accTitle: ثقل النقطة
accDescr: يبين المخطّط أن الشيفرة ذات نهاية صريحة مثل END-IF سهلة القراءة، أما في الشيفرة القديمة فتعمل النقطة منهي نطاق ضمنياً فتغلق الجمل غير المغلقة دفعة واحدة، ويتغيّر نطاق 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 بالمصدر وحده.
- تعريف الملف
- بيئة التنفيذ
- اتصال قاعدة البيانات
- بيئة المعاملة
- التحكّم في 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 دخل رمز النتيجة بعد كل عملية إدخال/إخراج.
قراءة أعطال الملفات وحكم EOF لا تبدأ بدونه. 14
flowchart TB
accTitle: تعريف الملف يُقرأ كمجموعة
accDescr: يبين المخطّط أن SELECT في FILE-CONTROL داخل ENVIRONMENT DIVISION وFD في DATA DIVISION يُقرآن كمجموعة، وأن FILE STATUS إن وُجد حمل رمز النتيجة بعد كل إدخال/إخراج فيكون نقطة انطلاق قراءة أعطال الملفات وحكم EOF.
fs1["SELECT في FILE-CONTROL"] --> fs3["تعريف ملف واحد كمجموعة"]
fs2["FD في FILE SECTION"] --> fs3
fs3 --> fs4["يدخل رمز النتيجة في FILE STATUS"]
fs4 -.-> fs5["نقطة انطلاق قراءة العطل وEOF"]
الشكل 17: هيئة الملف مكتوبة موزّعة على DIVISION اثنين.
EXEC SQL
إن ظهر فهذا SQL مضمَّن.
EXEC SQL
SELECT ...
END-EXEC.
هنا COBOL «وعاء متغيّرات المضيف»، وشروط الجلب وهدف التحديث في جانب SQL.
لذا الطريق المختصر قراءة محتوى EXEC SQL كـ SQL عادي.
EXEC CICS
إن ظهر فهذا سياق معاملة CICS. 15
EXEC CICS
RECEIVE MAP(...)
END-EXEC.
عند هذه اللحظة لم تعد القراءة دفعة مجرّدة. يلزم القراءة مع سياق خارجي: الشاشة، المعاملة، رمز الاستجابة، COMMAREA.
JCL وتعريف التنفيذ
في دفعة الحاسب المركزي ليس نادراً أن يكون أي مجموعة بيانات تُخصَّص فعلاً وبأي ترتيب يسير job خارج مصدر COBOL. إن نظرت إلى المصدر وحده ولم تعرف «أين يقع هذا الملف»، فغالباً ليست الشيفرة سيئة، بل النطاق الذي تنظر إليه لم يكف بعد.
flowchart TB
accTitle: العالم خارج المصدر
accDescr: يبين المخطّط أن ظهور EXEC SQL يجعل شروط الجلب الفعلية في جانب SQL، وظهور EXEC CICS يجعل السياق الخارجي مثل الشاشة والمعاملة، وأن تخصيص مجموعات البيانات وتدفّق job في دفعة الحاسب المركزي يقعان في JCL، فالعالم ينفصل خارج مصدر COBOL.
ex1["EXEC SQL"] --> ex7["انظر أيضاً خارج المصدر"]
ex3["EXEC CICS"] --> ex7
ex5["JCL أو تعريف التنفيذ"] --> ex7
ex7 -.-> ex2["شروط SQL وسياق الشاشة وتدفّق job"]
الشكل 18: الغموض قد لا يكون عيب الشيفرة، بل ضيق النطاق الذي تنظر إليه.
فروق المعالج (المترجم)
هذه المقالة مكتوبة وعوائل IBM في الذهن، لكنك قد تصادف عملياً Micro Focus أو COBOL على Linux / Windows. الهيكل مشترك فلا تتغيّر طريقة القراءة، غير أن نقاط «الكتابة نفسها والنتيجة مختلفة» محدّدة، فتثبيتها مسبقاً يمنع الحوادث.
| ما تنظر إليه | أنظمة z/OS (IBM Enterprise COBOL) | الأنظمة المفتوحة (Micro Focus، إصدارات Linux / Windows وغيرها) |
|---|---|---|
| ترميز الحروف | يُفترض EBCDIC 6 | يُفترض ASCII 6 |
| صيغة المرجع | الصيغة الثابتة الافتراض التقليدي. يمكن اختيار الحرّة أيضاً 1 | يحمل الثابت والحرّ، وأيّهما الافتراضي يتبع إعداد البناء 1 |
| كيف تُبحث copybook | تعيين مكتبة | تعيين مسار بحث في خيارات المترجم |
| اللهجة | — | يوجد خيار يبدّل «أي معالج يُوافق» |
الأشد أثراً ترميز الحروف. حتى مع PIC X(10) نفسه، قراءة ملف كُتب على z/OS كما هو على Windows تجعل حتى الأرقام بقيم بايت مختلفة. كثير من «نقلناه فتشوّه كل شيء» من هذا، ومشكلة مختلفة عن حديث 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 في شيفرة تبادل قيماً ثنائية مع نظام آخر، فاقرأه على أنه كُتب كذلك عن عمد.
أقصر إجراء للمقابلة مع بيئتك كالتالي.
- افتح تعريف البناء أولاً (makefile، JCL، إعداد المشروع). أي معالج وبأي خيارات يُترجم يتبيّن قبل المصدر.
- ثبّت صيغة المرجع (fixed / free). الخطأ هنا ثم التنسيق في المحرّر يكسر الشيفرة.
- ثبّت ترميز الحروف. EBCDIC أم ASCII يغيّر قراءة التفريغ.
- ضع علامة على عناصر عائلة
COMP. فرق المعالج يظهر هنا تقريباً.
flowchart TB
accTitle: أقصر إجراء للمقابلة مع بيئتك
accDescr: مخطّط لإجراء فتح تعريف البناء أولاً للتأكد من المعالج والخيارات، وتثبيت صيغة المرجع fixed أو free، وتثبيت ترميز الحروف إن كان EBCDIC أو ASCII، ووضع علامة على عناصر عائلة COMP التي يسهل ظهور فرق المعالج فيها.
ck1["افتح تعريف البناء أولاً"] --> ck2["ثبّت صيغة المرجع"]
ck2 --> ck3["ثبّت ترميز الحروف"]
ck3 --> ck4["ضع علامة على عناصر عائلة COMP"]
الشكل 19: أربع حركات قبل تحميل المصدر تمنع حوادث فرق المعالج.
8. ترتيب القراءة الأدنى
عندما تجد نفسك فجأة أمام قراءة COBOL، هذا الترتيب آمن.
- اغسل كل
COPYافتح copybook إن أمكن. وإلا ابحث عن listing أو المصدر بعد التوسيع - التقط تعريفات السجلات من المستوى
01اجمع الأعلى فيFILE SECTIONوWORKING-STORAGEوLINKAGE SECTION - اقرأ
PICوUSAGEميّز المبالغ والتواريخ والعدادات والرموز والأعلام - ابحث عن
READ/WRITE/REWRITE/CALL/EXEC SQL/EXEC CICSامسك الإدخال/الإخراج والحدود الخارجية أولاً - اتبع المسار الرئيس الأوّل فقط
من رأس
PROCEDURE DIVISIONارسم سلسلةPERFORM - انظر إلى
88وعناصر الحالة يسهل قراءة معنى EOF والسليم/الخاطئ ورمز النوع - ضع علامة على
REDEFINES/OCCURS DEPENDING ON/COMP-3ستؤثّر حتماً لاحقاً، فعلمّها مسبقاً كمواد خطرة - إن كان ملفاً فانظر إلى
FILE STATUSيقلّل كثيراً سوء قراءة أخطاء الإدخال/الإخراج
بهذا الترتيب لا تحتاج قراءة دقيقة للنص كلّه من البداية. COBOL أسهل بكثير إن ثبّت السجل، والحدود الخارجية، والمسار الرئيس ثم انتقلت إلى التفاصيل، بدل محاولة فهم 100% من اللحظة الأولى.
flowchart TB
accTitle: ترتيب القراءة الآمن
accDescr: مخطّط لترتيب القراءة: غسل COPY وتفحّص copybook، وجمع تعريفات السجلات من المستوى 01، وقراءة شكل العناصر بـ PIC وUSAGE، والإمساك بالإدخال/الإخراج والحدود الخارجية بالبحث، ثم تتبع المسار الرئيس بسلسلة PERFORM من رأس PROCEDURE DIVISION، ووضع علامة على المواد الخطرة.
ro1["اغسل كل COPY"] --> ro2["اجمع المستوى 01"]
ro2 --> ro3["اقرأ الشكل بـ PIC وUSAGE"]
ro3 --> ro4["ابحث عن الإدخال/الإخراج والحدود الخارجية"]
ro4 --> ro5["اتبع سلسلة PERFORM للمسار الرئيس"]
ro5 -.-> ro6["ضع علامة على المواد الخطرة"]
الشكل 20: ليس قراءة دقيقة للنص كلّه؛ املأ الخندق الخارجي بهذا الترتيب.
8.1 تمرين: اقرأ تعريف السجل هذا
الشرح وحده لا يثبّت، لذا نضع سجلاً صغيراً واحداً. أخرج الإجابة بنفسك أولاً ثم انظر إلى الحل أدناه.
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'، أي اسم شرط يصدق؟ - عند فتح هذا الملف في محرّر نصوص، أي عنصر يبدو مكسوراً؟
- اذكر أمرين لا يتبيّنان من هذا التعريف وحده.
الحل
-
74 بايتاً. التفصيل كالتالي.
العنصر الحساب البايتات CUST-IDX(8)8 CUST-NAMEX(20)20 CUST-KBNX1 CUST-BALANCECOMP-3 من 9 أرقام 5 CUST-HIST(8 + 4)× 3 مرّات36 FILLERX(4)4 المجموع 74 المستوى
88اسم شرط لذا لا يستهلك بايتات. عدّه خطأ شائع.FILLERبلا اسم فقط، و4 بايتات موجودة فعلاً. -
يبدأ من البايت 30. أمامه
8 + 20 + 1 = 29بايتاً، فيبدأ من التالي. -
يبدأ من البايت 55. يبدأ
CUST-HISTمن البايت 35، وكل عنصر 12 بايتاً، فالأوّل البايتات 35 - 46، والثاني 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فيُقرأ أرقاماً مثل20260317في بيئة ASCII. أما في بيئة EBCDIC فقد يبدو أرقاماً وتختلف قيمة البايت عن ASCII. -
مثلاً أمور كهذه.
- هل أُدخل هذا التعريف نفسه عبر
COPY. بلا النظر إلى جانب copybook لا تعرف إن كانت النسخة المستخدمة فعلاً. - هل ترميز الملف EBCDIC أم ASCII. يتغيّر مظهر
PIC XوPIC 9 DISPLAY. - هل يوجد تشغيل تدخل فيه قيم غير
'0'و'1'فيCUST-KBN. اسمَا الشرط المعرّفان اثنان فقط، وهذا ليس ضماناً ألا تأتي قيم أخرى. - صفات الملف نفسه (طول السجل، هل هو متغيّر الطول،
FILE STATUS). لا تتبيّن دونENVIRONMENT DIVISIONوFD.
- هل أُدخل هذا التعريف نفسه عبر
إن أخطأت السؤالين 1 و3 فارجع إلى جدول عدد الأرقام والبايتات في 5.3. سوء قراءة COBOL يبدأ غالباً من هنا.
9. المطبات الشائعة
أخيراً نجمع المواضع التي يعلق فيها المبتدئ باحتمال عالٍ جداً.
الظن أن REDEFINES «متغيّر آخر»
ليس كذلك. تقرأ المنطقة نفسها بشكل آخر. كتابة أحد الجانبين تغيّر مظهر الآخر أيضاً. 7
الظن أن 88 «bool مستقل»
ليس كذلك.
اسم أُعطي لقيمة العنصر السابق فقط. SET WS-OK TO TRUE يضع في الخلف القيمة المقابلة في العنصر الأساس. 3
تجاهل COPY وقراءة المتن وحده
الملف المفتوح لا يزال نصف الصورة. وجود تعريفات الحقول والأعلام المشتركة وhost variable خارجاً دفعة واحدة أمر عادي. 9
الظن أن MOVE إسناد بسيط
MOVE ليس memcpy مجرّداً.
بحسب نوع الجانب المستقبل قد يدخل تحويل ومواءمة أرقام وملء بأصفار واقتطاع وتحرير / عكس تحرير. 17
الاستهانة بأثر .
. في COBOL أثقل مما تتخيّل.
في الشيفرة القديمة بلا نهاية صريحة، سوء تقدير إلى أين تغلق هذه النقطة يخطئ قراءة تدفّق التحكّم. 12
الظن أن packed decimal أو EBCDIC «تشويه حروف»
ليس بالضرورة مكسوراً. كثيراً ما يكون أصلاً ليس سلسلة، أو ليس ASCII. 46
الظن أن ما بعد OCCURS DEPENDING ON موضع ثابت
العناصر اللاحقة لجدول متغيّر الطول قد يتحرّك موضعها بحسب القيمة. القراءة برأس طول ثابت تزيح حساب الإزاحة كلّه. 8
10. جدول سريع لما تنظر إليه أولاً
| الكلمة التي وجدتها | ما تفكّر فيه أولاً |
|---|---|
01 |
الأعلى في السجل أو المجموعة. من هنا تمسك الصورة الكاملة |
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 |
إدخال/إخراج الملف |
EXEC SQL |
معالجة قاعدة البيانات |
EXEC CICS |
معالجة المعاملة |
FILE STATUS |
رمز نتيجة الإدخال/الإخراج |
11. الخلاصة
COBOL ليس صعباً لأنه قديم. تعريف البيانات والملف الخارجي وسياق التنفيذ مرتبطون بإحكام، لذا يصعب رؤية المدخل الأوّل فقط.
نلخّص الحدّ الأدنى للقراءة مرّة أخرى كالتالي.
- امسك الخريطة بـ
DIVISION - اقرأ
DATA DIVISIONأولاً - اقرأ شكل العناصر بـ
PICوUSAGE - ضع علامة على
COMP-3وREDEFINESوOCCURSو88وCOPY - اتبع
PERFORMوREADوWRITEوCALL - ثبّت الحدود الخارجية بـ
FILE STATUSوEXEC SQLوEXEC CICS - لا تتهاون في أثر
.
إن بان هذا تحوّل COBOL من «سحر قديم غامض» إلى «لغة معالجة سجلات». التقنية القديمة ليست مخيفة لأن اسمها قديم، بل يصعب فهمها فجأة إن أخطأت مقياس النظر الأوّل. إن وافق مقياس الخريطة صارت القراءة عادية على نحو غير متوقّع.
flowchart TB
accTitle: اقرأ بمقياس موافق
accDescr: يبين المخطّط أنه إن وافقت المقياس بترتيب الإمساك بالخريطة عبر DIVISION، وقراءة الشكل في DATA DIVISION أولاً، وتتبع التدفّق بـ PERFORM وREAD ونحوهما، وتثبيت الحدود الخارجية بـ FILE STATUS وEXEC SQL وEXEC CICS، صار COBOL لغة معالجة سجلات تُقرأ عادة.
sm1["امسك الخريطة بـ DIVISION"] --> sm2["اقرأ الشكل في DATA DIVISION"]
sm2 --> sm3["اتبع التدفّق بـ PERFORM والإدخال/الإخراج"]
sm3 --> sm4["ثبّت الحدود الخارجية"]
sm4 -.-> sm5["يصير السحر القديم الغامض لغة معالجة سجلات"]
الشكل 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 clause” ↩ ↩2
-
IBM, “OCCURS DEPENDING ON clause” ↩ ↩2
-
IBM, “COPY statement” ↩ ↩2
-
IBM, “PERFORM statement” / IBM, “Procedure division structure” ↩
-
IBM, “Scope terminators” / IBM, “Coding a choice of actions” ↩ ↩2 ↩3 ↩4
-
IBM, “FILE STATUS clause” / IBM, “Using file status keys” ↩
-
IBM, “Computational items” ↩
-
IBM, “Elementary move rules” ↩
مقالات ذات صلة
أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.
معالجة الأعطال لا تنتهي بالاستعادة ── قالب postmortem (منع التكرار) للفرق الصغيرة
إن انتهت معالجة العطل عند «أصلحنا واعتذرنا»، تكرر العطل نفسه. نكيّف مبدأ blameless postmortem للفرق الصغيرة، ونقدّم قالباً يُكتب في ساعة،...
مدخل إلى ADR (سجلّ قرار العمارة) ── أقلّ وسيلة لتوثيق «لماذا اخترنا هذا التصميم» في التطوير الصغير
لا تخبرنا الشيفرة «لماذا اتُّخذ هذا القرار». نشرح كيفية توثيق أسباب قرارات التصميم عبر ADR (Architecture Decision Record) بصيغة Markdown ...
التوافق الخلفي لواجهات DLL وCOM ── جدول قرار لتحديد أيّ تغيير يكسر جهة الاستدعاء
أيّ تغيير في مكوّنات DLL أو COM يكسر جهة الاستدعاء؟ نرتّب الطبقات الثلاث للتوافق: الثنائيّ، والمصدريّ، والسلوكيّ، ونقدّم جدول قرار حسب نو...
إدارة إصدارات مخطّط قاعدة بيانات تطبيقات الأعمال ── ممارسات الترحيل لمنع «اختلاف قاعدة البيانات من عميل لآخر»
دليل عمليّ لإدارة إصدارات مخطّط قاعدة بيانات تطبيقات الأعمال الموزَّعة على عملاء متعدّدين. نشرح PRAGMA user_version وتنفيذ الترحيل الأمام...
التعديل الآمن على تطبيق أعمال قديم بلا اختبارات ── ممارسة اختبار التوصيف وإعادة الهيكلة
لإجراء تعديلات آمنة على تطبيق أعمال بلا اختبارات، نشرح خطوات اختبار التوصيف (أسلوب Golden Master) الذي يثبّت السلوك الحالي، وكيفيّة صنع ن...
أين يتصل هذا الموضوع
ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.
الاستشارات التقنية ومراجعة التصميم
موضوع يتناسب جيّداً مع الاستشارة التقنيّة ومراجعة التصميم، بما يشمل طريقة قراءة أصول COBOL القائمة، ونقطة الدخول إلى التعديل، وفهم الحدود الخارجيّة، وترتيب التقدير الأوّليّ قبل الترحيل.
التحقيق في الأخطاء وتحليل السبب الجذري
التعامل مع الأعطال بُعيد تسلّم النظام، وتتبّع الموضع الذي ينشأ فيه التعارض داخل أصول COBOL، عملان يسهل التقدّم فيهما ضمن التحقيق في الأعطال وتحليل الأسباب.
الأسئلة الشائعة
أسئلة شائعة حول موضوع هذه المقالة.
- من أين أبدأ قراءة مصدر COBOL؟
- قراءة PROCEDURE DIVISION وحدها لا تعطيك إلا نصف الصورة. COBOL قبل أن يكون لغة منطق هو بقوة لغة تعريف سجلات، لذا انظر أولاً إلى DATA DIVISION. الترتيب الآمن: اغسل كل COPY وتفحّص الـ copybook، اجمع تعريفات السجلات من المستوى 01، اقرأ شكل العناصر بـ PIC وUSAGE، ابحث عن READ وWRITE وCALL وEXEC SQL وEXEC CICS لتثبيت الإدخال/الإخراج والحدود الخارجية، ثم اتبع سلسلة PERFORM من رأس PROCEDURE DIVISION للمسار الرئيس فقط.
- ماذا يعني PIC S9(7)V99 COMP-3؟
- PIC هو شكل العنصر، وUSAGE هو التمثيل الذي يُحفظ به. S9(7)V99 عدد موقّع من 7 أرقام صحيحة + رقمين عشريين، لكن V فاصلة عشرية منطقية ولا يدخل حرف نقطة في البيانات. COMP-3 هو packed decimal ويظهر كثيراً في بنود المبالغ والضرائب والعدادات والمعدّلات. رؤيته كنص تجعلّه يبدو مكسوراً وهذا متوقّع، لذا النظر إلى التفريغ بمزاج CSV أو UTF-8 يوقع حوادث.
- كيف أفهم المستوى 88 وREDEFINES في COBOL؟
- 88 ليس متغيّر bool مستقلّاً، بل اسم شرط (condition-name) يُعطى لقيمة العنصر السابق. SET WS-OK TO TRUE يضع في الخلف القيمة المقابلة في العنصر الأساس. REDEFINES آلية لرؤية المنطقة نفسها بشكل آخر؛ ليست نسخاً بل أقرب إلى union في عائلة C. كتابة أحد الجانبين تغيّر مظهر الآخر أيضاً، لذا يكثر استخدامها للتمييز بين أنواع السجلات على المنطقة نفسها.
- ماذا أفعل عندما تكثر جمل COPY فلا أرى الصورة كاملة؟
- COPY هو include وقت الترجمة، لذا قد لا يكون المصدر المفتوح أمامك الشكل المكتمل بعد. دفع تعريفات السجلات والأعلام المشتركة وhost variable لـ SQL والواجهات الخارجية إلى copybook أمر شائع جداً. إن صعبت القراءة فابحث أولاً إن كان بإمكانك رؤية المصدر بعد التوسيع أو compiler listing. في IBM Enterprise COBOL خيار MDECK يكتب مصدر الإدخال بعد معالجة المكتبات.
الملف الشخصي للمؤلف
صفحة الملف الشخصي لمؤلف المقالة.
غو كومورا
مؤسّس شركة كومورا سوفت ذ.م.م.
يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.