Perl - YAML


Во всех примерах буду использовать такой скрипт


$ cat script.pl 
#!/usr/local/bin/perl

use uni::perl   qw| :dumper  |;
use YAML::XS    qw| LoadFile |;

my $config = LoadFile('test.yml');

warn dumper $config;

exit;

Типы данных

Строка


test
$ perl ./script.pl 
"test"

Спец. символы будут экранированны


Here text - "And what about Yaml?"
$ perl ./script.pl 
"Here text - \"And what about Yaml?\""

Принудительное приведение типа к строке


test1: !str 1
test2: 2018-05-05

$ perl ./script.pl 
{
  test2 => "2018-05-05",
  test1 => bless( do{\(my $o = 1)}, 'str' )
}


Длинная строка: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facere itaque autem perferendis tenetur similique dolores unde. Placeat laudantium, necessitatibus, dolor quisquam hic at tempore eum nulla, ex vitae minima possimus?"

$ perl ./script.pl 
{
  "Длинная строка" => "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facere itaque autem perferendis tenetur similique dolores unde. Placeat laudantium, necessitatibus, dolor quisquam hic at tempore eum nulla, ex vitae minima possimus?"
}

Null или undef


test: ~
    $ perl ./script.pl 
{
  test => undef
}

Булевы


test1:
  ok: true
  success: 1

test2:
  ok: false
  success: 0

$ perl ./script.pl 
{
  test1 => {
    ok => 1,
    success => 1
  },
  test2 => {
    ok => "",
    success => 0
  }
}

У перла, лож - ноль, пустая строка, undef. Все остальное - истина, и даже ноль в кавычках(“0”), к сожалению

Числа


zero: 0
one: 1
thousand: 1,000
negative-thousand: -1,000

$ perl ./script.pl 
{
  thousand => "1,000",
  one => 1,
  "negative-thousand" => "-1,000",
  zero => 0
}

Простые структуры данных

Список


$ cat test.yml 
- Apples
- Orange
- Banana
- Mango

$ perl ./script.pl 
[
  "Apples",
  "Orange",
  "Banana",
  "Mango"
]

Вложенный список


-
  - Apples
  - Orange
  - Banana
  - Mango

$ perl ./script.pl 
[
  [
    "Apples",
    "Orange",
    "Banana",
    "Mango"
  ]
]

Хеш


user:
  first_name: vasya
  last_name: pupkin
  age: 29

$ perl ./script.pl 
{
  user => {
    last_name => "pupkin",
    age => 29,
    first_name => "vasya"
  }
}

Список хещей или хеш со списком, вобщем комбинация


- user1:
    name: vasya
    age: 12
    skils:
      - perl
      - python
      - javascript

- user2:
    name: petya
    age: 15
    skils: 
      - java
      - c++
      - assembler

$ perl ./script.pl
[
  {
    user1 => {
      skils => [
        "perl",
        "python",
        "javascript"
      ],
      age => 12,
      name => "vasya"
    }
  },
  {
    user2 => {
      name => "petya",
      age => 15,
      skils => [
        "java",
        "c++",
        "assembler"
      ]
    }
  }
]

Важно! отступы при перечислении важны!

Так например если сделать так


  - user1:
  name: vasya
  age: 12
    

То получиться не совсем то что ожидалось


$ perl ./script.pl 
[
  {
    user1 => undef,
    name => "vasya",
    age => 12
  }
]
    

JSON формат

Также можно сворачивать в json формат


user1: { name: vasya;, age: 12, skils: [ perl, python, javascript ] }
user2: { name: petya, age: 15, skils: [ java, c++, assembler ] }

результат сериализации не измениться. These are called “Flow collections”. Чтобы это не значило :)


$ perl ./script.pl 
{
  user1 => {
    skils => [
      "perl",
      "python",
      "javascript"
    ],
    age => 12,
    name => "vasya;"
  },
  user2 => {
    name => "petya",
    age => 15,
    skils => [
      "java",
      "c++",
      "assembler"
    ]
  }
}

Многострочный текст

Можно использовать знак | или |-. Результат будет одинаковый На самом деле нет.
|- - не добавляет в конец ВСЕЙ строки, символ переноса строки

Каждая строка должна начинаться с переноса строки, в том числе и первая


lorem: |
  Lorem ipsum dolor sit amet,
  consectetur adipisicing elit.
  Accusantium, molestias!

$ perl ./script.pl 
{
  lorem => "Lorem ipsum dolor sit amet,\nconsectetur adipisicing elit.\nAccusantium, molestias!\n"
}

lorem: |-
  Lorem ipsum dolor sit amet,
  consectetur adipisicing elit.
  Accusantium, molestias!

$ perl ./script.pl 
{
  lorem => "Lorem ipsum dolor sit amet,\nconsectetur adipisicing elit.\nAccusantium, molestias!"
}

Однострочный текст

Также можно использовать символы: >, >- или вовсе без них


one-line-text:
  one
  line
  text

$ perl ./script.pl 
{
  "one-line-text" => "one line text"
}

Можно даже писать в “столбик”


commands:
    - do something with --a long --list of --parameters 
    - do something
      with 
      --a long 
      --list of 
      --parameters 

$ perl ./script.pl 
{
  commands => [
    "do something with --a long --list of --parameters",
    "do something with --a long --list of --parameters"
  ]
}

Ссылки


references:
    value1: &reference "Don't repeat yourself!"
    value2: *reference 

$ perl ./script.pl 
{
  references => {
    value2 => "Don't repeat yourself!",
    value1 => ${\$VAR1->{references}{value2}}
  }
}

& - определить ссылку(метку) на эл.
* - использовать ссылку(разыменовать)

Причем перл у себя будет хранить именно сслыку, в удобном ему формате

Также можно ссылаться и на сложные структуры данных аля “наследование”


test1: &hello
  test1.1: 11
  test1.2: 12

test2:
  test1: *hello
  test21: 1

$ perl ./script.pl 
{
  test1 => {
    "test1.1" => 11,
    "test1.2" => 12
  },
  test2 => {
    test1 => $VAR1->{test1},
    test21 => 1
  }
}

Работа с документом

Вырезка документа


test: 1

---

test2: 2

---

test3: 3

$ perl ./script.pl 
{
  test3 => 3
}

да… не такой эффект я ожидал. А оказывается все просто:
yaml все правильно сделал, разбил документ на три части, и вернул три структуры. А мы приняли только одну т.к. в скалярном контексте возвращается последний эл.


$ cat test.yml
test: 1

---

test2: 2

---

test3: 3

cat script.pl
#!/usr/local/bin/perl

use uni::perl   qw| :dumper  |;
use YAML::XS    qw| LoadFile |;

my ( $part1, $part2, $part3 ) = LoadFile('test.yml');

warn dumper $part1;
warn dumper $part2;
warn dumper $part3;

exit;

$ perl ./script.pl 
{
  test => 1
}
{
  test2 => 2
}
{
  test3 => 3
}

На что стоит обратить внимание

Даже если строка в yaml файле разбита на несколько, то она все еще считается нормальной. Пример


note:
  fonmix:player:monitoring:[Filial
  key.Filial
  system_key] -> {
  json
  monitoring
  }

test_str: { hello
world! }
test: 1

$ perl script.pl 
{
  test => 1,
  test_str => {
    "hello world!" => undef
  },
  note => "fonmix:player:monitoring:[Filial key.Filial system_key] -> { json monitoring }"
}

Так что, хоть на 10 строк разбить строку, она нормально распарситься

PS доп. смотри ансибл - ансибл