FlowingDev

شرح YAML: لغة الإعدادات التي تشبه قصيدة شعر

تعلم أساسيات YAML، صيغة البيانات سهلة القراءة للبشر والمستخدمة في ملفات الإعدادات، والتواصل مع الواجهات البرمجية (APIs)، والحفاظ على إعدادات مشروعك منظمة.

جرّب الأداة: محرر YAML

في جملة واحدة

YAML هي طريقة صديقة للبشر لكتابة البيانات المهيكلة، تستبدل الأقواس المعقوفة وعلامات الاقتباس الموجودة في أقرانها بالمسافات البادئة الأنيقة لقائمة مشتريات مُنظمة جيدًا.

المشكلة التي تحلها

في البداية، كانت الفوضى. ثم أتت ملفات الإعدادات. الصيغ القديمة مثل .ini كانت بسيطة ولكنها لم تستطع التعامل مع البيانات المعقدة والمتداخلة. ثم وصلت XML، قوية ومنظمة، ولكنها مليئة بالكلام والعلامات (tags) لدرجة أن قراءتها كانت تشبه تجميع أثاث IKEA بتعليمات مكتوبة بلغة قانونية معقدة. كرهها البشر.

بعدها، أتت JSON (JavaScript Object Notation) وكانت تحسينًا هائلاً. كانت خفيفة الوزن، وترتبط مباشرة بهياكل البيانات في معظم لغات البرمجة، وكانت أسهل بكثير على العينين من XML. ولكن بالنسبة للملفات التي كان على البشر كتابتها وتحريرها كثيرًا - مثل سكربتات DevOps، وإعدادات التطبيقات، ونصوص الترجمة الدولية - كانت صيغة JSON لا تزال تبدو وكأنها مهمة شاقة. كل تلك الأقواس المعقوفة والفواصل وعلامات الاقتباس كانت ضوضاء بصرية ومن السهل إفسادها.

وهنا يأتي دور YAML. الاسم هو اختصار تكراري يجسد روحها تمامًا: "YAML Ain't Markup Language" (YAML ليست لغة ترميز). صُممت من الألف إلى الياء لجمهور أساسي واحد: الإنسان الذي يحدق في الشاشة. أخذت نفس هياكل البيانات الأساسية الموجودة في JSON (أزواج المفتاح-القيمة، القوائم، والقيم البسيطة) وسألت: "ما هو الحد الأدنى المطلق من الصيغة التي نحتاجها لتمثيل هذا؟"

كان الجواب هو المسافات البادئة. باستخدام المسافات البيضاء للدلالة على الهيكل، أنشأت YAML صيغة غالبًا ما تكون نظيفة بما يكفي لتكون ذاتية التوثيق. صُنعت لعالم الإعدادات، حيث يتفوق الوضوح وسهولة التعديل على احتياجات التحسين للآلة في واجهة برمجية عالية الإنتاجية.

كيف تعمل من الداخل

"سحر" YAML هو مجرد مجموعة بسيطة ومتسقة من القواعد لتحويل نص بمسافات بادئة إلى بيانات مهيكلة. هي مجموعة فائقة (superset) من JSON، مما يعني أنه يمكنك غالبًا لصق كود JSON صالح في ملف YAML وسيعمل ببساطة. لكن القوة الحقيقية تأتي من صيغتها الأصلية المبسطة.

اللبنات الأساسية: Scalars، وSequences، وMappings

تتلخص جميع البيانات في YAML في ثلاثة أشياء:

  1. Mappings (أو الكائنات Objects): هذه هي أزواج key: value الكلاسيكية. المفتاح هو نص (string)، والقيمة يمكن أن تكون أي شيء: mapping آخر، أو sequence، أو scalar.

    # A simple mapping
    character: "Bilbo Baggins"
    race: "Hobbit"
    age: 111
    
  2. Sequences (أو القوائم Arrays): هذه هي قوائم مرتبة من العناصر. يتم الإشارة إلى كل عنصر بشرطة ومسافة (- ).

    # A sequence of strings
    fellowship_members:
      - Frodo Baggins
      - Samwise Gamgee
      - Gandalf
      - Legolas
      - Gimli
    
  3. Scalars (أو القيم البسيطة): هذه مجرد قيمة واحدة، مثل نص، أو رقم، أو قيمة منطقية (boolean). YAML ذكية جدًا في تخمين النوع. 123 هو رقم، true هي قيمة منطقية، و Hello world هو نص. لا تحتاج عادةً إلى علامات اقتباس، ولكن يجب عليك استخدامها إذا كان من الممكن تفسير النص الخاص بك بشكل خاطئ (على سبيل المثال، "true"، "1.23").

الخلطة السرية: المسافات البادئة والمسافات البيضاء

هذا هو أهم مفهوم في YAML. لا توجد أقواس معقوفة {} أو أقواس مربعة [] لإظهار التداخل. بدلاً من ذلك، تستخدم المسافات البادئة فقط. القاعدة بسيطة: إذا كان السطر يحتوي على مسافة بادئة أكثر من السطر الذي يسبقه، فإنه يصبح تابعًا لذلك السطر.

دعنا ندمج لبناتنا الأساسية. إليك ملف تعريف شخصية مع قائمة بمحتويات المخزون.

# A nested structure
character:
  name: "Gollum"
  aliases:
    - "Sméagol"
    - "My Precious"
  possessions:
    - item: "The One Ring"
      description: "A plain gold ring, surprisingly heavy."
    - item: "A fish"
      description: "Juicy and sweet!"
  is_wretched: true

انظر إلى الهيكل. name، aliases، possessions، و is_wretched كلها خصائص لـ character لأنها ذات مسافة بادئة تحته. الـ sequence aliases هي قيمة داخل الـ mapping character. والـ sequence possessions تحتوي على كائني mapping، كل منهما يحتوي على item و description.

مقدار المسافة البادئة لا يهم، طالما أنه متسق داخل نفس الكتلة. مسافتان هما المعيار المتعارف عليه في المجتمع. ولكن يجب عليك استخدام المسافات، وليس علامات الجدولة (tabs). استخدام الجدولة هو الطريقة رقم #1 لإدخال نفسك في عالم من الألم الخفي.

حيل متقدمة: Anchors، وAliases، وTags

لدى YAML بعض الميزات المتقدمة التي تفتقر إليها JSON، مصممة للحفاظ على ملفاتك DRY (Don't Repeat Yourself - لا تكرر نفسك).

  • المراسي (&) والأسماء المستعارة (*): إذا كان لديك جزء من البيانات تحتاج إلى إعادة استخدامه، يمكنك إعطاؤه اسمًا باستخدام مرساة (&anchor_name) ثم الإشارة إليه في مكان آخر باستخدام اسم مستعار (*anchor_name).

    # Define a default user profile with an anchor
    default_user: &default_user_profile
      theme: "dark"
      notifications: "enabled"
      permissions: "read-only"
    
    # Now create specific users who inherit the defaults
    users:
      - name: "Alice"
        # Use an alias to pull in the default profile
        <<: *default_user_profile
        # And override a specific key
        permissions: "admin"
      - name: "Bob"
        # Bob gets the standard profile
        <<: *default_user_profile
    

    هنا، << هو مفتاح دمج خاص. كل من Alice و Bob يحصلان على الملف الشخصي الافتراضي، ولكن يتم استبدال قيمة المفتاح permissions لـ Alice. هذا منقذ حقيقي في الإعدادات المعقدة.

  • العلامات (Tags) (!!): عادةً ما تستنتج YAML الأنواع، ولكن يمكنك أن تكون صريحًا باستخدام العلامات. يمكن أن يكون هذا مفيدًا لتجنب الغموض. على سبيل new_york، إذا كنت تريد النص "12.0" وليس الرقم 12.0.

    version: !!str 12.0 # Force this to be a string
    not_a_boolean: !!str "no" # Force this to be a string
    

قصص من الواقع

قضية مسار العمل (Pipeline) المختفي

تم تكليف مهندسة DevOps مبتدئة، دعنا نسميها "كلوي"، بإضافة فحص أمني جديد إلى مسار CI/CD الخاص بشركتهم، المحدد في ملف gitlab-ci.yml. أضافت المهمة الجديدة، دفعت الكود، و... لا شيء. عمل الـ pipeline، لكن مهمة الفحص الجديدة لم تكن موجودة في أي مكان. لم تفشل؛ لقد اختفت ببساطة. لمدة ساعتين، راجعت كلوي صيغة السكربت، وإعدادات الـ runner، وتعريفات المرحلة. أخيرًا، في حالة من الإحباط، طلبت من مهندس أقدم إلقاء نظرة. مسحت عينا المهندس الأقدم الملف لمدة خمس ثوانٍ قبل أن يشير إلى سطر واحد. كانت كلوي قد أضافت مسافة بادئة لمهمتها الجديدة بثلاث مسافات بدلاً من المسافتين المستخدمتين في كل مكان آخر. رأى محلل YAML أنها تابعة بشكل غير صحيح للمهمة السابقة، وليست مهمة جديدة على المستوى الأعلى، وتجاهلها بصمت.

الدرس: في YAML، المسافة البيضاء هي جزء من البنية (syntax). مسافة واحدة في غير مكانها يمكن أن تغير معنى ملفك بالكامل. استخدم linter أو محررًا منظمًا يعرض شجرة البيانات بشكل مرئي لاكتشاف هذه الأخطاء على الفور.

ملف الإعدادات الذي تحول إلى غابة

كانت شركة ناشئة صغيرة تدير بيئات تطبيقاتها (التطوير، الاختبار، الإنتاج) باستخدام ملف config.yml واحد. في البداية، كان الأمر بسيطًا. ولكن مع إضافة المزيد من البيئات (prod-us، prod-eu، dev-feature-x)، انفجر الملف. تم نسخ ولصق كتل ضخمة من الإعدادات لعناوين URL لقواعد البيانات، ومفاتيح API، وأعلام الميزات لكل بيئة، مع تغييرات طفيفة فقط. أصبح الملف وحشًا مكونًا من 500 سطر، وتغيير قيمة مشتركة واحدة، مثل إعداد المهلة الزمنية، يتطلب البحث عنها واستبدالها في خمسة أماكن مختلفة. رأى موظف جديد، قادم حديثًا من شركة أكبر، هذا وقدم مراسي YAML. عرّف كتلة &default_config مع جميع الإعدادات المشتركة. ثم، كل إعداد بيئة استخدم ببساطة اسمًا مستعارًا للإعداد الافتراضي (<<: *default_config) واستبدل القيم القليلة المختلفة. تقلص الملف المكون من 500 سطر إلى أقل من 100 سطر.

الدرس: لا تكرر نفسك. إذا وجدت نفسك تنسخ وتلصق كتلًا كبيرة داخل ملف YAML، فقد حان الوقت لتعلم واستخدام المراسي والأسماء المستعارة.

مشكلة النرويج

كان مطور يبني ميزة تتيح للمستخدمين تحديد بلدهم من قائمة منسدلة. كانت قائمة رموز البلدان مخزنة في ملف YAML بسيط: supported_countries: [US, DE, UK, NO]. أثناء الاختبار، اشتكى المستخدمون من النرويج (NO) من أنهم لا يستطيعون التسجيل. قام المطور بتصحيح الأخطاء في الكود لساعات، وتتبع المتغيرات، لكنه لم يتمكن من رؤية المشكلة. كانت القيمة NO يتم تمريرها من الواجهة الأمامية بشكل صحيح. أخيرًا، قام بفحص البيانات التي يتم تحميلها من ملف YAML. كانت مصفوفة supported_countries في برنامجه هي ['US', 'DE', 'UK', false]. كان محلل YAML، متبعًا إصدارًا أقدم من المواصفات، قد فسر NO غير المقتبسة على أنها قيمة منطقية لـ "false".

الدرس: عندما تكون في شك، ضع علامات اقتباس حول نصوصك. أي قيمة scalar يمكن أن تبدو كرقم ("1.0")، أو قيمة منطقية ("yes"، "no"، "on"، "off"), أو قيمة خاصة يجب أن تكون مقتبسة بشكل صريح لتجنب مفاجأة في التحليل.

الأخطاء والفخاخ الشائعة

  • استخدام علامات الجدولة (tabs) بدلاً من المسافات. هذه هي الخطيئة الكبرى في YAML. تمنع المواصفات استخدام علامات الجدولة. ولأنها غير مرئية، يمكن أن تسبب أخطاء تحليل يصعب العثور عليها بشكل جنوني. قم بتهيئة محرر النصوص الخاص بك لاستخدام المسافات لملفات YAML.
  • مسافات بادئة غير متسقة. إذا كان أحد عناصر القائمة مزاحًا بمسافتين والعنصر التالي بأربع، فستقضي وقتًا سيئًا. سيتم تحليل الهيكل بشكل غير صحيح. حافظ على مستويات المسافة البادئة متسقة.
  • نسيان وضع علامات اقتباس حول النصوص الغامضة. "مشكلة النرويج" هي مثال كلاسيكي. النصوص مثل Yes، No، true، false، On، Off سيتم تحليلها على أنها قيم منطقية. الأرقام التي تبدأ بأصفار أو تحتوي على أحرف خاصة قد يتم تحليلها بشكل غير صحيح. عندما تكون في شك، ضعها بين "علامات اقتباس".
  • الارتباك في النصوص متعددة الأسطر. نسيان الفرق بين | (نمط حرفي، يحافظ على الأسطر الجديدة) و > (نمط مطوي، يحول الأسطر الجديدة إلى مسافات). يمكن أن يؤدي هذا إلى تشويه كتلة النص أو السكربت الذي قمت بتنسيقه بعناية.
  • قيم null غير متوقعة. مفتاح لا يتبعه أي شيء بعد النقطتين (key: ) هو قيمة null. غالبًا ما يكون هذا حذفًا عرضيًا ويمكن أن يسبب فشلًا صامتًا إذا لم يتحقق الكود الخاص بك من وجود null.

لماذا يجب أن تكون على رادارك

إذا كنت تكتب كودًا في عام 2024، فلا يمكنك الهروب من YAML. هي الملك المتوج بلا منازع في عالم الإعدادات.

  • DevOps وInfrastructure-as-Code: Kubernetes، وAnsible، وDocker Compose، وGitHub Actions، وAWS CloudFormation، وعدد لا يحصى من الأدوات الأخرى تستخدم YAML كلغة تعريف أساسية لها.
  • إعدادات التطبيقات: العديد من أطر العمل (مثل Symfony وRuby on Rails) والتطبيقات تستخدم YAML لملفات الإعدادات لأنها سهلة القراءة والتعديل للمطورين.
  • مولدات المواقع الثابتة: أدوات مثل Jekyll وHugo تستخدم YAML في "frontmatter" لتعريف البيانات الوصفية للمشاركات والصفحات.

معرفة YAML لا تقتصر فقط على كتابة ملفات الإعدادات. إنها تتعلق بفهم بنية الأنظمة التي تعمل معها. القدرة على اكتشاف خطأ دقيق في المسافة البادئة أو معرفة متى يجب استخدام مرساة يمكن أن تكون الفرق بين إصلاح سريع ويوم ضائع في تصحيح الأخطاء.

تعمق أكثر

  • YAML Spec 1.2.2: المصدر الرسمي للحقيقة. إنه كثيف، لكنه المرجع النهائي.
  • Wikipedia: YAML: نظرة عامة ممتازة وعالية المستوى على تاريخ وميزات وإصدارات اللغة.
  • Learn YAML in Y minutes: ورقة غش رائعة من صفحة واحدة مع أمثلة حية تغطي 80% مما ستحتاجه على الإطلاق.
  • YAML Lint: مدقق عبر الإنترنت لا يقدر بثمن في العثور على تلك الأخطاء الصياغية المزعجة وفهم ما "يراه" المحلل.
  • GitHub Docs: Workflow syntax for GitHub Actions: مثال واقعي ممتاز لنظام معقد معرف بالكامل في YAML. دراسته تكشف عن العديد من الأنماط الشائعة.

انتهينا من النظرية. حان وقت التطبيق — 100% في متصفحك.

جرّب الأداة: محرر YAML