在YAML conf文件合併哈希

2009年7月31日, prashant
提起下: 技術

YAML是相當方便的編寫配置文件。 主要優點是,它像文本文件中讀取。 這個作品真的很好,如果你的配置文件是平坦的(不分層),並沒有重複。
如果您的配置文件中有重複,然後分離出這些元素和重用它們是有意義的。 我的意思是 - 讓我們說你的配置文件看起來像這樣:

 發展:
   input_location:common_input
   output_location:dev_location
  郵箱:
     smtp_server:您的服務器
    登錄:your_login
    密碼:top_secret
生產:
   input_location:common_input
   output_location:dev_location
  郵箱:
     smtp_server:您的服務器
    登錄:your_login
    密碼:top_secret 

假設上面的代碼在/ tmp / test.yml這裡你可以看到如何在Python和Ruby
$cat readyml.py

 #!的/ usr / bin中/ env的蟒蛇
從pprint為PP進口pprint
 #Debian中需要安裝python-YAML
從的YAML進口負載,load_all,轉儲
哈希=負載(開放(“/ TMP / test.yml的”))
 PP(哈希['發展']) 


$ cat readyml.rb

  #!/ USR / BIN / env的紅寶石
需要“PP”
哈希= YAML的::負載(的File.Open(“/ TMP / test.yml的”)。)
 PP哈希['發展'] 

這裡是一個方便的Ruby版本的班輪
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]'或者你可以嘗試在irb或Python控制台相同。

請注意,在上面的代碼片斷,一切都以外的輸出位置是相同的開發和生產的一部分。 這是YML節點標識符來搶救。 想法很簡單,有一組默認值和重寫他們在不同的地方。
你可以把它拆開如下:

 默認:與默認
   input_location:common_input
   output_location:dev_location
  郵箱:
     SENDER_NAME:發送方
     smtp_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_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_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文件的解決方案,它是更好地挖成YAML或別的東西restucture比conf文件。 但是,這是你的電話了。

評論

  • 完整的453頁的文件還列出了潛在的領域
    整合,包括私有化的拾垃圾,合併的城市和
    韋恩縣衛生部門和底特律公立學校合作
    娛樂。 該提案沒有包括任何...

  • 熟悉交易的人士說,雙方仍然哈希為合併後的公司名稱。 但這位人士說,正在考慮的一個思路,就是選擇一個名字,沒有單詞“德意志”或“紐約證券交易所”的縮寫,。 ...

  • 是惱人的,它不合併遞歸。 我是能夠使我balphp圖書館的一種變通方法。

博客評論由Disqus