How to include a YAML file inside a YAML file in Ruby
I found a way to address my scenario using ERB.
I monkey patched YAML module to add two new methods
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
I have three YAML files.
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") %>
Parse the yaml file using the method YAML::load_erb
instead of the method YAML::load
.
config = YAML::load_erb('all_config.yml')
config['mod1']['age'] # 30
config['mod2']['menu'] # menu1
Caveats:
- Does not support document merge
- Last include overwrites same named keys
Parse YAML to key value and include yaml categories
You could use the YAML#load_file, read each line and adapt it to your need:
foo = YAML.load_file('file.yaml').map do |key, value|
value.map { |k, v| "#{key}/#{k}=#{v}" }
end
foo.each { |value| puts value }
# test/line1=line 1 text
# test/line2=line 2 text
# test/line3=line 3 text
# options/item1=item 1 text
# options/item2=item 2 text
# options/item3=item 3 text
Rubygem: How to load information of a yaml file
You should be able to load app yaml files by doing this in your gem:
YAML.load_file('config/my_gem.yml')
This requires that the working directory is the root of your Rails application – which is the case when you invoke the rails command while in that directory.
How can I include a YAML file inside another?
No, standard YAML does not include any kind of "import" or "include" statement.
How to inject a line to a YAML file using Ruby
YAML is a serialized version of an object, either a hash or an array. Because of the way the serializer does it, according to the specification, we can't stick a line into the output any old place, it has to be syntactically correct. And, the easiest way to do that is to let the YAML parser and serializer handle it for you.
For instance:
require 'yaml'
foo = {'a' => 1}
puts foo.to_yaml
Which outputs:
---
a: 1
and is a simple hash in YAML format.
We can do a round-trip showing that's correct:
bar = foo.to_yaml
YAML.load(bar) # => {"a"=>1}
A more complex object shows how it can get tricky:
foo = {'a' => [1,2], 'b' => {'c' => [3, 4]}}
puts foo.to_yaml
which results in:
---
a:
- 1
- 2
b:
c:
- 3
- 4
There are other ways to designate an array, but that's the default for the serializer. If you added a line, depending on what you're adding it'd have to be before a:
or b:
, which would be a pain when writing code or appended to the file after - 4
.
Instead, we can load and parse the file, munge the resulting object however we want, then rewrite the YAML file, knowing the syntax will be right.
In the following code, imagine that bar
is the result of using YAML's load_file
, which reads and parses a YAML file, instead of my use of load
which only parses the serialized object:
require 'yaml'
bar = YAML.load("---\na: [1]\n") # => {"a"=>[1]}
I can modify bar
:
bar['b'] = {'c' => [2,3,4]}
Here's the modified object:
bar # => {"a"=>[1], "b"=>{"c"=>[2, 3, 4]}}
and serializing using to_yaml
will write the correct YAML:
bar.to_yaml # => "---\na:\n- 1\nb:\n c:\n - 2\n - 3\n - 4\n"
If that was:
File.write('foo.yaml', bar.to_yaml)
you'd have accomplished the change without any real hassle.
Instead of simply overwriting the file I'd recommend following safe file overwriting practices by writing to a new file, renaming the old, renaming the new to the name of the old, then deleting the renamed old file. This helps to make sure the file doesn't get clobbered if the code or machine dies causing you to lose all your data.
How do I parse a YAML file in Ruby?
Maybe I'm missing something, but why try to parse the file? Why not just load the YAML and examine the object(s) that result?
If your sample YAML is in some.yml
, then this:
require 'yaml'
thing = YAML.load_file('some.yml')
puts thing.inspect
gives me
{"javascripts"=>[{"fo_global"=>["lazyload-min", "holla-min"]}]}
How to get Ruby to retrieve specific data from a YAML file?
You can read the required information from your YAML like this:
require 'yaml'
people = YAML.load_file('the_filename.yaml')
puts people['userA']['fruit'] #=> 'apple'
puts people['userB']['canDance'] #=> true
Note: Your YAML file seems to be valid and can be read by the default Ruby YAML parser. But it uses a very special and uncommon syntax. I suggest writing your YAML like this:
userA:
nick: cat
fruit: apple
canDance: true
age: 20
userB:
nick: dog
fruit: orange
canDance: false
age: 23
Related Topics
Ruby Class Instance Variables and Inheritance
Rails - Displaying Foreign Key References in a Form
Ruby CSV Parsing String with Escaped Quotes
Pg Error Could Not Connect to Server: Connection Refused Is the Server Running on Port 5432
Are Ruby 1.9 Regular Expressions Equally Powerful to a Context Free Grammar
"Errno::Eaccess...Permission Denied" Running Compass Watch
Change Error Field Name in Rails
How to Load Some Activerecord Models from a Yaml File and Save Them to the Db
How to Find a Model's Relationships
How to Look Up Elevation Data by Lat/Lng
Capistrano 3 Execute Within a Directory
Using Nokogiri HTML Builder to Create Fragment with Multiple Root Nodes
In Ruby, How to I Control the Order in Which Test::Unit Tests Are Run