2010-02-17 89 views

回答

14

我找到了一種方法來解決我的方案使用ERB。

我猴子修補YAML模塊添加兩個新方法

module YAML 
    def YAML.include file_name 
     require 'erb' 
     ERB.new(IO.read(file_name)).result 
    end 

    def YAML.load_erb file_name 
     YAML::load(YAML::include(file_name)) 
    end 
end 

我有三個YAML文件。

mod1_config.yml

mod1: 
    age: 30 
    city: San Francisco 

mod2_config.yml

mod2: 
    menu: menu1 
    window: window1 

all_config.yml

<%= YAML::include("mod1_config.yml") %> 
<%= YAML::include("mod2_config.yml") %> 

解析yaml文件使用方法YAML::load_erb而不是方法YAML::load

config = YAML::load_erb('all_config.yml') 
    config['mod1']['age'] # 30 
    config['mod2']['menu'] # menu1 

注意事項:

  1. 不支持文檔合併
  2. 最後包括覆蓋同名鍵
+0

我得到錯誤'私人方法'包括'調用Psych:Module(NoMethodError)'任何猜測我該如何解決它? 我在'initializers/yaml.rb'中添加了YAML模塊 – swapab

1
  1. !include不是一個指令,而是一個標記。
  2. 它不是Python的(或PyYAML)的功能,但「poze」庫的特點:

    poze.configuration暴露了一個名爲默認指令包括。

  3. YAML規範沒有定義這樣的標準標籤。

+0

YAML SP ec沒有標籤'!include'。我希望有人在「poze」庫中寫了一個類似於自定義標籤的自定義標籤。我想它的時間自己寫自定義標籤:-) –

0

取決於你需要它。如果你需要傳輸文件,你可以用base64編碼內部的yaml文件。

8

如果你的目標是避免重複在YAML文件,不一定包括外部文件,我建議做這樣的事情:

development: &default 
    adapter: mysql 
    encoding: utf8 
    reconnect: false 
    database: db_dev 
    pool: 5 
    username: usr 
    password: psw 
    host: localhost 
    port: 3306 

dev_cache: 
    <<: *default 

new: 
    <<: *default 
    database: db_new 

test: 
    <<: *default 
    database: db_test 
+2

您可能需要'YAML :: ENGINE.yamler ='syck''才能運行http://stackoverflow.com/a/6140900/414220 – evanrmurphy

2

我使用這個:

load_config。RB(初始化)

cf_1 = YAML::load(File.read("/etc/my_app/config.yml")) 
cf_2 = YAML::load(File.read(File.join(Rails.root, "config", "config.yml"))) 
CONFIG = cf_1.merge(cf_2) 

以後,你可以通過做訪問配置值:

CONFIG['value'] 
15

如果你在Rails中,YAML可以包括ERB。

結合一起,這裏是你如何使用<%= %>包括來自另一個文件:

的database.yml

<% if File.exists?('/tmp/mysql.sock') %> 
<%= IO.read('config/database.mysql.yml') %> 
<% else %> 
<%= IO.read('config/database.sqlite.yml') %> 
<% end %> 

database.sqlite.yml

sqlite: &defaults 
    adapter: sqlite3 
    pool: 5 
    timeout: 5000 

development: 
    <<: *defaults 
    database: db/development.sqlite3 

test: 
    <<: *defaults 
    database: db/test.sqlite3 

production: 
    <<: *defaults 
    database: db/production.sqlite3 

database.mysq l.yml

development: 
    adapter: mysql2 
    # ... the rest of your mysql configuration ... 
1

如果你只是想從另一個YAML文件繼承,也可以是擴展紅寶石YAML庫提供此功能你所要求的寶石:

https://github.com/entwanderer/yaml_extend

https://rubygems.org/gems/yaml_extend

用法

yaml_extend添加方法YAML#ext_load_file到YAML。

此方法與原始YAML#load_file類似,通過擴展文件繼承來實現。

例子

# start.yml 
extends: 'super.yml' 
data: 
    name: 'Mr. Superman' 
    age: 134  
    favorites: 
     - 'Raspberrys' 

-

# super.yml 
data: 
    name: 'Unknown' 
    power: 2000 
    favorites: 
     - 'Bananas' 
     - 'Apples' 

基本繼承

YAML.ext_load_file('start.yml') 

結果

data: 
    name: 'Mr. Superman' 
    age: 134 
    power: 2000 
    favorites: 
     - 'Bananas' 
     - 'Apples' 
     - 'Raspberrys'