如何在Ruby中的YAML文件中包含YAML文件

时间:2010-02-17 04:08:21

标签: ruby-on-rails ruby yaml

在YAML中是否有自定义标记用于ruby以在YAML文件中包含YAML文件?

#E.g.:  
--- !include
filename: another.yml

前一段时间曾问过similar问题,但没有相关答案。

我想知道Ruby是否有一些类似于this的自定义标记用于Python。

7 个答案:

答案 0 :(得分:16)

如果您在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.mysql.yml

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

答案 1 :(得分: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::load_erb方法而不是方法YAML::load解析yaml文件。

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

<强>注意事项:

  1. 不支持文档合并
  2. 最后包括覆盖相同的命名键

答案 2 :(得分: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

答案 3 :(得分: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']

答案 4 :(得分:1)

  1. !include不是指令,而是标签。
  2. 它不是Python(或PyYAML)的一个功能,而是“poze”库的一个特性:

    poze.configuration公开了一个名为include。

  3. 的默认指令
  4. YAML规范没有定义这样的标准标记。

答案 5 :(得分:1)

如果您只想继承另一个YAML文件,那么有一个gem可以通过扩展ruby 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'

答案 6 :(得分:0)

取决于你需要它。如果需要传输文件,可以使用base64编码内部yaml文件。