Hashes המתמזגות בקבצי conf yaml

31 יולי 2009 על ידי Prashant · תגובות
מתויק תחת: טכנולוגיה

YAML הוא די נוח לכתיבת קבצי תצורה. היתרון העיקרי הוא, זה נשמע כמו קובץ טקסט. זה עובד ממש טוב אם הקובץ config שלך הוא שטוח (ללא היררכיה) ואין לו חזרות.
אם הקובץ תצורות שלך יש חזרות אז זה הגיוני להפריד את אותם אלמנטים ושימוש חוזר בהם. כוונתי היא זו - נניח הקובץ config שלך נראה כך:

  פיתוח:
   input_location: common_input
   output_location: dev_location
   דואר אלקטרוני:
     smtp_server: Your_Server
     כניסה: your_login
     סיסמה: top_secret
 הפקה:
   input_location: common_input
   output_location: dev_location
   דואר אלקטרוני:
     smtp_server: Your_Server
     כניסה: your_login
     סיסמה: top_secret 

בהנחה מעל הקוד tmp / / test.yml כאן היא איך אתה יכול לקרוא פייתון ורובי
$cat readyml.py

 #! / Usr / bin / env python
 מ pprint יבוא pprint כמו PP
 # של דביאן צריך להתקין python-yaml
 מ יבוא yaml עומס dump, load_all
 hash = עומס (פתוח ('/ tmp / test.yml "))
 PP (חשיש ["פיתוח"]) 


$ cat readyml.rb

  #! / Usr / bin / env רובי
 דורשים "עמ '
 hash = YAML :: עומס (File.open ('/ tmp / test.yml "). לקרוא)
 PP חשיש ["פיתוח"] 

כאן הוא תוחם שימושי 1 לגרסה רובי
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' או שאתה יכול לנסות אותו IRB או קונסולת פייתון.

יש לציין כי קטע הקוד הנ"ל, הכל מלבד המיקום הפלט הוא אותו חלק בפיתוח ייצור. זה המקום שבו מזהה הצומת yml בא להציל. הרעיון הוא פשוט להיות קבוצה של ערכי ברירת המחדל ואת לעקוף אותם במקום אחר.
אתה יכול למשוך את זה לבד באופן הבא:

  המחדל: & המחדל
   input_location: common_input
   output_location: dev_location
   דואר אלקטרוני:
     SENDER_NAME השולח: *
     smtp_server: Your_Server
     כניסה: your_login
     סיסמה: top_secret
 פיתוח:
   <<: * ברירת המחדל
 הפקה:
   <<: * ברירת המחדל
   output_location: prod_location 


$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$

יופי, זה עובד (tm)!.
ניתן לטעון שאנחנו נסחר קצת בהירות קצת קסם. הנה הסבר קטן: & * ו <<: & שהוא תג העוגן יכול להיות מובן מזהה הצומת, * הוא התייחסות צמתים <<: מייצג מיזוג חשיש.

לפרטים נוספים ראו באפשרות מפרט yaml או ויקיפדיה
עד כאן טוב ויפה אבל יש מלכוד כאן, אלה מתמזג חשיש לא רקורסיבית. המשמעות היא זו: נניח אתה רוצה להיות שם השולח שונה עבור דואר בשתי סביבות, אתה עלול להתפתות לבצע את הפעולות הבאות:

  המחדל: & המחדל
   input_location: common_input
   output_location: dev_location
   דואר אלקטרוני:
     SENDER_NAME השולח: *
     smtp_server: Your_Server
     כניסה: your_login
     סיסמה: top_secret
 פיתוח:
   <<: * ברירת המחדל
   דואר אלקטרוני:
     SENDER_NAME: sender_dev
 הפקה:
   <<: * ברירת המחדל
   output_location: prod_location
   דואר אלקטרוני:
     SENDER_NAME: sender_prod 

בואו לבדוק

$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
nil
$

אופס, משהו השתבש, הבעיה כאמור היא כי המיזוג חשיש לא רקורסיבית ובעוד מיזוג זה החליף האלקטרוני של ברירת המחדל בדואר הייצור שבה יש רק מפתח אחד. הפתרון / לעקוף היא לפרוש רמה אחת יותר:

  common_settings: & common_settings
 input_location: common_input
 output_location: dev_location
 mail_defaults: & mail_defaults
  SENDER_NAME השולח: *
   smtp_server: Your_Server
   כניסה: your_login
   סיסמה: top_secret

 המחדל: & המחדל
   <<: * Common_settings
   דואר אלקטרוני:
     <<: * Mail_defaults
 פיתוח:
   <<: * ברירת המחדל
 הפקה:
   <<: * ברירת המחדל
   דואר אלקטרוני:
     <<: * Mail_defaults
     SENDER_NAME: sender_prod

בואו לבדוק שוב

$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$

אמרת שיש לך רמה אחת יותר קינון, גם אתה בהחלט יכול לפרוש רמה אחת יותר, אבל אז הוא הופך להיות בלגן. לכן, אם אתה לא מנסה לכתוב פתרון מגדלי האנוי בקובץ conf, עדיף restucture הקובץ conf מאשר לחפור לתוך yaml או משהו אחר. אבל זו השיחה בכל מקרה.