-1

I am experimenting with the merging maps feature of Kwalify gem from the documentation

When I load the YAML in my ruby script, I don't see the values getting merged.

parser = Kwalify::Yaml::Parser.new(@validator)

document = parser.parse_file(File.join(__dir__, "test_files", "values.yml"))

I think there is something wrong with my understanding. It would be really helpful if I can get any much better example for understanding maps merging feature of YAML along with code to retrieve merged values of YAML.

YAML schema

type: map
mapping:
  "group":
    type: map
    mapping:
      "name": &name
        type: str
        required: yes
      "email": &email
        type: str
        pattern: /@/
        required: no
  "user":
    type: map
    mapping:
      "name":
        <<: *name             # merge
        length: { max: 16 }   # add
      "email":
        <<: *email            # merge
        required: yes         # override

YAML input

group:
  name: foo
  email: foo@mail.com
user:
  name: bar
  email: bar@mail.com
krisnik
  • 1,406
  • 11
  • 18

1 Answers1

0

You shouldn't see anything change in values.yml because the merging maps feature is used in your schema.

Basically, this is what's happening. This part of your schema

"user":
  type: map
  mapping:
    "name":
      <<: *name             # merge
      length: { max: 16 }   # add
    "email":
      <<: *email            # merge
      required: yes         # override

Is converted to

"user":
  type: map
  mapping:
    "name":
      type: str
      required: yes
      length: { max: 16 }   # add
    "email":
      type: str
      pattern: /@/
      required: yes         # override

You can use this feature in the values.yml if you want to see the change.

# values.yml
group: &foo
  name: foo
  email: foo@mail.com
user:
  <<: *foo
  email: bar@mail.com

then:

parser.parse_file('values.yml')
=> {"group"=>{"name"=>"foo", "email"=>"foo@mail.com"}, "user"=>{"name"=>"foo", "email"=>"bar@mail.com"}}

See how the name foo is merged but the email is overwritten.

cozyconemotel
  • 1,121
  • 2
  • 10
  • 22
  • Ok, Thank you. My assumption was that using merge in schema, I will be able to retrieve a merged collection when the values are parsed using schema. Is there any way to accomplish this? For example: If I want to collect set of nodes in the YAML, one way is to store metadata of the nodes I require and parse the YAML. Is there any other way? – krisnik Jul 22 '17 at 05:34
  • I feel like that use case is too uncommon for someone to make a gem for. How about just load the metadata and data separately, then merge them? Check out [this question](https://stackoverflow.com/questions/5581285/merging-multi-dimensional-hashes-in-ruby). – cozyconemotel Jul 24 '17 at 02:40