Việc sáp nhập băm trong các tập tin conf yaml

31 Tháng Bảy 2009 bởi Prashant · B́nh luận
Nộp theo: công nghệ

YAML là khá tiện dụng để viết các tập tin cấu h́nh. Chính lợi thế đó, nó đọc tập tin văn bản. Điều này làm việc thực sự tốt nếu tập tin cấu h́nh của bạn là bằng phẳng (không có hệ thống phân cấp) và không có lần lặp lại.
Nếu tập tin cấu h́nh của bạn có lặp lại sau đó nó làm cho cảm giác để phân biệt những yếu tố và tái sử dụng chúng. Những ǵ tôi có nghĩa là chúng ta hăy nói rằng bạn tập tin cấu h́nh của bạn trông như thế này:

  phát triển:
   input_location: common_input
   output_location: dev_location
   mail:
     smtp_server: your_server
     đăng nhập: your_login
     mật khẩu: top_secret
 sản xuất:
   input_location: common_input
   output_location: dev_location
   mail:
     smtp_server: your_server
     đăng nhập: your_login
     mật khẩu: top_secret 

Giả sử trên mă trong / tmp / test.yml ở đây là làm thế nào bạn có thể đọc trong python, ruby
$cat readyml.py

 # / Usr / bin / env python
 từ pprint nhập khẩu pprint như Trang
 # Trong debian cần phải cài đặt python-yaml
 từ nhập khẩu yaml tải, băi chứa, load_all
 hash = tải (mở ('/ tmp / test.yml'))
 Trang (hash ['phát triển']) 


$ cat readyml.rb

  # / Usr / bin / env ruby
 yêu cầu 'Trang'
 hash = YAML :: tải (File.open ('/ tmp / test.yml').)
 Trang băm ['phát triển'] 

đây là một tiện dụng lót cho phiên bản ruby
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' hoặc bạn có thể thử trong IRB hoặc giao diện điều khiển python.

Lưu ư rằng trong đoạn mă trên, tất cả mọi thứ khác hơn là đầu ra vị trí tương tự trong phát triển và một phần sản xuất. Đây là nơi định danh nút yml đến để giải thoát. Ư tưởng là đơn giản có một bộ các giá trị mặc định và ghi đè lên tại địa điểm khác nhau.
Bạn có thể kéo nó ra ngoài như sau:

  mặc định: - mặc định
   input_location: common_input
   output_location: dev_location
   mail:
     SENDER_NAME: người gửi
     smtp_server: your_server
     đăng nhập: your_login
     mật khẩu: top_secret
 phát triển:
   <<: * Mặc định
 sản xuất:
   <<: * Mặc định
   output_location: prod_location 


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

Tuyệt vời, nó hoạt động (tm).
Có thể cho rằng chúng tôi giao dịch ở một số rơ ràng cho một chút ma thuật. Đây là một lời giải thích nhỏ: &, và <<: & là anchor thẻ có thể được hiểu như là định danh nút, * là nút tham chiếu và <<: là viết tắt của hợp nhất băm.

Để biết thêm chi tiết xem một trong hai thông số kỹ thuật yaml hoặc wikipedia
Cho đến nay rất tốt nhưng có một nắm bắt ở đây, những sáp nhập băm không phải là đệ quy. Nó có nghĩa là: chúng ta hăy nói rằng bạn muốn có tên người gửi thư trong hai môi trường khác nhau, bạn có thể bị cám dỗ để làm như sau:

  mặc định: - mặc định
   input_location: common_input
   output_location: dev_location
   mail:
     SENDER_NAME: người gửi
     smtp_server: your_server
     đăng nhập: your_login
     mật khẩu: top_secret
 phát triển:
   <<: * Mặc định
   mail:
     SENDER_NAME: sender_dev
 sản xuất:
   <<: * Mặc định
   output_location: prod_location
   mail:
     SENDER_NAME: sender_prod 

Cho phép kiểm tra

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

Rất tiếc, một cái ǵ đó đă đi sai, vấn đề như đă đề cập ở trên là hợp nhất hash không phải là đệ quy và khi hợp nhất nó thay thế thư mặc định của thư sản xuất mà chỉ có một ch́a khóa. Giải pháp / công tŕnh xung quanh là cuộn thêm một cấp độ:

  common_settings: & common_settings
 input_location: common_input
 output_location: dev_location
 mail_defaults: & mail_defaults
  SENDER_NAME: người gửi
   smtp_server: your_server
   đăng nhập: your_login
   mật khẩu: top_secret

 mặc định: - mặc định
   <<: * Common_settings
   mail:
     <<: * Mail_defaults
 phát triển:
   <<: * Mặc định
 sản xuất:
   <<: * Mặc định
   mail:
     <<: * Mail_defaults
     SENDER_NAME: sender_prod

Cho phép kiểm tra lại

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

Bạn có nói rằng bạn có thêm một mức độ làm tổ, bạn có thể chắc chắn cuộn thêm một cấp nữa, nhưng sau đó nó trở thành một mớ hỗn độn. V́ vậy, nếu bạn không cố gắng để viết giải pháp cho tháp Hà Nội trong một tập tin conf, nó là tốt hơn để restucture tập tin conf hơn đào vào yaml hay cái ǵ khác. Nhưng đó là cuộc gọi của bạn anyway.