الجواب المختصر
- افتح منسِّق JSON، والصق الملف الأول، واضبط المسافة البادئة على مسافتين، وعلِّم خانة ترتيب مفاتيح كل كائن. ثم انسخ الناتج.
- افتح مقارن النصوص والصقه في الحقل الأيمن الأول.
- وافعل الشيء نفسه بالملف الثاني، في الحقل الآخر.
ما يضيء الآن حقيقي: قيمة تغيّرت، أو مفتاح ظهر، أو مدخل ذهب. أما فروق التنسيق والمفاتيح المعاد ترتيبها التي كانت ستغرق مقارنة عادية فقد زالت، لأن الجانبين كُتبا بالهجاء نفسه قبل أن تبدأ المقارنة.
وليست لأي من الصفحتين وظيفة شبكية البتة، وذلك جدير بالعلم: فالـ JSON الذي يقارنه الناس كثيراً ما يكون ملف إعدادات ما تزال فيه بيانات الدخول.
لماذا مقارنة JSON الخام جلّها ضجيج
JSON لا يبالي بالمسافات، ولا يمنح ترتيب المفاتيح معنى. فالمستند نفسه قد يكون سطراً أو أربعمئة، ومفاتيحه بترتيب كتابتها أو بترتيب أخرجته مكتبة ما — والأدوات تعيد كتابة الاثنين بلا استئذان. جانب مضغوط والآخر مبسوط؛ جانب حُفظ يدوياً والآخر بمسلسِل يرتب أبجدياً: مقارنة الأسطر ترى ملفين غريبين.
وأسوأ حالتين تكفيان بياناً. الملف المصغَّر سطر واحد، فمقارنته سطر واحد متغيّر هائل: صحيح وعديم النفع. وملفان فيهما المحتوى نفسه بترتيب آخر يقارَنان على أن كل شيء تغيّر، والجواب الصادق كان «لا شيء».
ما الذي تصلحه الصيغة القياسية للمنسِّق
تمرير الملفين على المنسِّق نفسه بالإعدادات نفسها هو بالضبط ما تحتاجه المقارنة: هجاء واحد لكل مستند.
- المسافة البادئة نفسها تضع كل مفتاح في سطره: فتعمل المقارنة سطراً سطراً، وتستطيع علاماتها اللفظية أن تشير إلى القيمة الوحيدة التي تغيّرت داخل سطر.
- المفاتيح المرتبة تضع الجانبين في ترتيب واحد، فيكفّ الترتيب عن كونه فرقاً. والترتيب بحسب قراءة المفاتيح لا نقاط الترميز —
item2قبلitem10— وهو مطبَّق على الجانبين سواء. - ولا شيء غير ذلك يتحرك. هذا المنسِّق يبقي الأعداد بالأرقام التي كتبتها، ويبقي المفاتيح المكررة بدل حسمها: فالتقييس لا يستطيع هو نفسه اختراع فرق. ودليل المنسِّق يشرح لماذا هذا أندر مما ينبغي.
وتحفظ صادق: الناتج المرتب هو المستند وقد تحركت مفاتيحه. فإن كانت أداة لاحقة تعبأ بترتيب المفاتيح — وقليل يفعل، لكنه موجود — فعامل النسختين المرتبتين على أنهما الشيء المقارَن، لا بديلَي الأصلين.
قراءة الناتج، وأخذه معك
يعلِّم المقارن الأسطر المحذوفة في جانب والمضافة في الجانب الآخر، ويبرز داخل السطر المتغيّر الكلمات المختلفة: وعلى صيغة قياسية يكون ذلك عادة القيمة الوحيدة التي انتقلت من false إلى true. والوسط الذي لم يتغيّر يُطوى إلى عدد، فتُقرأ إعدادات من ألفي سطر فيها ثلاثة تعديلات كثلاث فقرات قصيرة.
والتنزيل رقعة موحَّدة، ملف .patch: الصيغة التي تفهمها مراجعة الشيفرة. وهي تصف الصيغتين القياسيتين، وذلك عادة ما تريده المراجعة على كل حال: التغيير، من دون إعادة التنسيق.
والوصفة نفسها تصلح لكل ما تتكلمه الصفحتان. فـ YAML وXML يتقيّسان بالطريقة نفسها؛ ولملفين على الشكل نفسه من مصدرين مختلفين، مفاتيح التجاهل في المقارن — المسافات وحالة الأحرف والأسطر الفارغة — نسخة أخف من الفكرة نفسها.
إن كنت تفعل هذا كل أسبوع
تنسيقان ولصقتان: تعيش الخطوات في صفحتين لأن كل صفحة تؤدي عملاً واحداً، وكلٌّ منهما تثبت وحدها أن شيئاً مما لصقته لم يذهب إلى أي مكان. غير أن الاثنتين مفتوحتا المصدر: رخصة MIT، ووحدات ES بلا تبعيات — محلِّل المنسِّق يحفظ ترتيب المفاتيح والأرقام، والمقارنة خوارزمية Myers — ولكلٍّ README يشرحها.
فإن كان هذا جزءاً من يومك، وجِّه وكيل برمجة إلى المستودع واطلب صفحة بحقلين تقيِّس وهي تقارن: فـ parseJson وprintJson وcompareText على بعد ثلاثة استيرادات. الوحدات كُتبت لتُقرأ، وأخذها هو بالضبط ما وُجدت الرخصة له.