Почему Ruby YAML иногда добавляет '2' после символьной трубы (|)? - PullRequest
0 голосов
/ 02 июля 2018

При работе с модулем Ruby YAML я столкнулся с поведением, которое мне не понятно.

String # to_yaml для многострочной строки иногда добавляет символ «2» сразу после символа канала: «| 2» против просто «|».

В частности, он делает это, когда первая строка пуста.

Есть хоть какая-то подсказка, почему?

Вот пример:

C:\Users\Burdette>irb
irb(main):001:0> RUBY_VERSION
=> "2.2.6"
irb(main):002:0> require 'yaml'
=> true
irb(main):003:0> s = <<EOT
irb(main):004:0" 1
irb(main):005:0" 2
irb(main):006:0" 3
irb(main):007:0" EOT
=> "1\n2\n3\n"
irb(main):008:0> puts s.to_yaml
--- |
  1
  2
  3
=> nil
irb(main):009:0> s = "\n" + s
=> "\n1\n2\n3\n"
irb(main):010:0> puts s.to_yaml
--- |2

  1
  2
  3
=> nil
irb(main):011:0> exit

1 Ответ

0 голосов
/ 02 июля 2018

| обозначает буквальный скаляр. За ним следует Block Scalar Header , который может указывать уровень отступа литерала и указывать, является ли он "сжатым" или нет. Громить - это раздевать финальный перевод строки. Например, когда мы удаляем последний перевод строки ...

2.4.3 :059 > puts "\n1\n2\n3".to_yaml
--- |2-

  1
  2
  3
 => nil 

... YAML добавляет -, чтобы указать, что последний символ новой строки удален.

Точно так же, 2 говорит убрать первые два пробела из каждой строки. Это позволяет сохранить начальные символы новой строки в исходной строке.

2.4.3 :061 > puts "\n  1\n2\n3".to_yaml
--- |2-

    1
  2
  3
 => nil 

Обычно уровень отступа не задан, поэтому вы видите |, и значение отступа выводится из непустой строки первой строки. В этом примере выводится 2.

2.4.3 :062 > puts "1\n2\n3".to_yaml
--- |-
  1
  2
  3
 => nil 

Но когда в первой строке содержатся неоднозначности, это необходимо сделать явным. Вот полные документы из спецификации на это.

8.1.1.1. Индикатор блочного отступа

Как правило, уровень отступа скалярного блока определяется по его первой непустой строке. Для любой из первых пустых строк является ошибкой содержать больше пробелов, чем в первой непустой строке.

Обнаружение завершается неудачно, когда первая непустая строка содержит начальные символы пространства содержимого. Содержимое может начинаться с символа табуляции или символа «#».

Если обнаружение не удастся, YAML требует, чтобы уровень отступа для контента задавался с использованием явного индикатора отступа. Этот уровень указывается как целое число дополнительных пространств отступов, используемых для содержимого, относительно его родительского узла.

Всегда допустимо указывать индикатор отступа для блочного скалярного узла, хотя процессор YAML должен выдавать явный индикатор отступа только в тех случаях, когда обнаружение не удастся.

В вашем случае YAML совершает круговые обходы просто отлично с или без явного индикатора. Он может получить отступ от первой непустой строки. Я мог бы предположить, что конкретная реализация YAML является консервативной и делает отступ явным, когда первая строка пуста.

Есть много способов выразить то же самое в YAML. Например, добавление дополнительного кавычка и переключателей Ruby в кавычки.

2.4.3 :055 > puts " \n1\n2\n3\n".to_yaml
--- " \n1\n2\n3\n"
 => nil 

Почему бы не это?

--- |2-

  1
  2
  3

Вероятно, из-за того, что его нелегко прочитать и что дополнительное пространство очень легко упустить, будучи готовым человеком, YAML предназначен как для людей, так и для машин. Чтобы действительно знать, вам придется прочитать код библиотеки YAML и, возможно, онлайн-обсуждения во время ее разработки. Я собираюсь догадаться, что было решено быть явным, когда есть вероятность двусмысленности или путаницы безопаснее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...