Explained YAML Syntax and Ruby Parsing

I am new to YAML and Ruby. I use the following Ruby code to parse the YAML file:

obj = YAML::load_file('test.yml') 

Are the following contents of the YAML file for 'test.yml' valid?

Case 1:

 test 

In this case, I do not specify the value of test (something like test : true ), but my Ruby parsing code does not throw an error. I thought this was an invalid YAML syntax.

Case 2:

 :test : true 

In this case, the Ruby code treats test as a character instead of a string, and when I do puts obj[:test] , it returns the result as "true". Is this a ruby ​​thing? Do other languages ​​interpret it as the string ":test" ?

Case 3:

 :test : true :test : false 

In this case, instead of throwing an error to override :test , my Ruby code takes the most recent value for :test (which is false ). Why is this? Is the YAML syntax to allow overriding of elements, in which case only the last value is taken?

+4
source share
2 answers

Case 1: YAML allows unordered scalars or bare strings not enclosed in quotation marks. Compared to quoted strings, they are less flexible since you cannot use certain characters without creating ambiguous syntax, but the Ruby parser does support them.

 1.9.3-p448 > YAML::parse('test').to_ruby => "test" 

Case 2: As you may have guessed, this is specific to Ruby, since YAML does not have the concept of “characters”. When converting YAML mapping to a Ruby hash, scalar keys starting with a colon are interpreted as characters instead of strings.

Case 3:. In the definition of YAML mapping, keys must be unique, so a strict parser should throw an error when you give your example. The Ruby analyzer seems to be softer and allows the same key to be set multiple times using a rule with the latest values. This is also allowed in Ruby's own hashes.

 1.9.3-p448 > YAML::parse("test: true\ntest: false").to_ruby => {"test"=>false} 1.9.3-p448 > { 'test' => true, 'test' => false } => {"test"=>false} 
+4
source

A great way to find out how the YAML parser is converted to / from Ruby structures is to write the Ruby code that outputs YAML and see what it does:

Here's the main hash:

 require 'yaml' foo = {'test' => true} # => {"test"=>true} foo.to_yaml # => "---\ntest: true\n" 

Hash using a character as a key:

 foo = {test: true} foo.to_yaml # => "---\n:test: true\n" 

A hash with conflicting keys, forcing the first to clamp the last:

 foo = {test: true, test: false} foo # => {:test=>false} foo.to_yaml # => "---\n:test: false\n" 

YAML creates a hash, but hashes cannot duplicate keys; If they do, then the collision leads to a second replacement of the first.

The YamlForRuby Yaml Cookbook is also a great resource.

+2
source

Source: https://habr.com/ru/post/1498430/


All Articles