How to Include a Yaml File Inside a Yaml File in Ruby

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:

  1. Does not support document merge
  2. 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



Leave a reply



Submit