Spec-Zone.ru › Ruby 3.3

модуль Psych

Обзор

Psych — это парсер и генератор YAML. Psych использует libyaml [Главная страница: pyyaml.org/wiki/LibYAML] или [репозиторий git: github.com/yaml/libyaml] для своих возможностей парсинга и генерации YAML. В дополнение к обёртке над libyaml, Psych также умеет сериализовать и десериализовать большинство объектов Ruby в формат YAML и из него.

МНЕ НУЖНО СРАЗУ РАЗОБРАТЬ ИЛИ СГЕНЕРИРОВАТЬ YAML!

# Parse some YAML
Psych.load("--- foo") # => "foo"

# Emit some YAML
Psych.dump("foo")     # => "--- foo\n...\n"
{ :a => 'b'}.to_yaml  # => "---\n:a: b\n"

У вас есть больше времени? Продолжайте чтение!

YAML Парсинг

Psych предоставляет ряд интерфейсов для парсинга документа YAML, от низкого до высокого уровня, в зависимости от ваших потребностей в парсинге. На самом низком уровне находится событийный парсер. На среднем уровне доступ к исходному YAML AST, а на самом высоком уровне — возможность распаковки YAML в объекты Ruby.

YAML Генерация

Psych предоставляет ряд интерфейсов от низкого до высокого уровня для создания документов YAML. Очень похожие на интерфейсы парсинга YAML, Psych предоставляет на самом низком уровне событийную систему, на среднем уровне построение YAML AST, а на самом высоком уровне преобразование объекта Ruby непосредственно в документ YAML.

API высокого уровня

Парсинг

Парсер YAML высокого уровня, предоставляемый Psych, просто принимает YAML в качестве входных данных и возвращает структуру данных Ruby. Для получения информации об использовании парсера высокого уровня см. Psych.load

Чтение из строки

Psych.safe_load("--- a")             # => 'a'
Psych.safe_load("---\n - a\n - b")   # => ['a', 'b']
# From a trusted string:
Psych.load("--- !ruby/range\nbegin: 0\nend: 42\nexcl: false\n") # => 0..42

Чтение из файла

Psych.safe_load_file("data.yml", permitted_classes: [Date])
Psych.load_file("trusted_database.yml")

Обработка исключений

begin
  # The second argument changes only the exception contents
  Psych.parse("--- `", "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

Генерация

Интерфейс генератора высокого уровня самый простой. Psych просто принимает структуру данных Ruby и преобразует её в документ YAML. См. Psych.dump для получения дополнительной информации о выводе структуры данных Ruby.

Запись в строку

# Dump an array, get back a YAML string
Psych.dump(['a', 'b'])  # => "---\n- a\n- b\n"

# Dump an array to an IO object
Psych.dump(['a', 'b'], StringIO.new)  # => #<StringIO:0x000001009d0890>

# Dump an array with indentation set
Psych.dump(['a', ['b']], :indentation => 3) # => "---\n- a\n-  - b\n"

# Dump an array to an IO with indentation set
Psych.dump(['a', ['b']], StringIO.new, :indentation => 3)

Запись в файл

В настоящее время нет прямого API для вывода структуры Ruby в файл:

File.open('database.yml', 'w') do |file|
  file.write(Psych.dump(['a', 'b']))
end

API среднего уровня

Парсинг

Psych предоставляет доступ к AST, созданной в результате парсинга документа YAML. Это дерево построено с использованием Psych::Parser и Psych::TreeBuilder. AST можно свободно исследовать и изменять. См. Psych::parse_stream, Psych::Nodes и Psych::Nodes::Node для получения дополнительной информации о работе с синтаксическими деревьями YAML.

Чтение из строки

# Returns Psych::Nodes::Stream
Psych.parse_stream("---\n - a\n - b")

# Returns Psych::Nodes::Document
Psych.parse("---\n - a\n - b")

Чтение из файла

# Returns Psych::Nodes::Stream
Psych.parse_stream(File.read('database.yml'))

# Returns Psych::Nodes::Document
Psych.parse_file('database.yml')

Обработка исключений

begin
  # The second argument changes only the exception contents
  Psych.parse("--- `", "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

Генерация

На среднем уровне происходит построение AST. Эта AST идентична AST, используемой при парсинге документа YAML. Пользователи могут вручную построить AST, и AST знает, как выводить себя как документ YAML. См. Psych::Nodes, Psych::Nodes::Node и Psych::TreeBuilder для получения дополнительной информации о построении YAML AST.

Запись в строку

# We need Psych::Nodes::Stream (not Psych::Nodes::Document)
stream = Psych.parse_stream("---\n - a\n - b")

stream.to_yaml # => "---\n- a\n- b\n"

Запись в файл

# We need Psych::Nodes::Stream (not Psych::Nodes::Document)
stream = Psych.parse_stream(File.read('database.yml'))

File.open('database.yml', 'w') do |file|
  file.write(stream.to_yaml)
end

API низкого уровня

Парсинг

Парсер самого низкого уровня следует использовать, когда входные данные YAML уже известны, и разработчик не хочет платить за построение AST или автоматическое определение и преобразование в объекты Ruby. См. Psych::Parser для получения дополнительной информации об использовании событийного парсера.

Чтение в структуру

parser = Psych::Parser.new(TreeBuilder.new) # => #<Psych::Parser>
parser = Psych.parser                       # it's an alias for the above

parser.parse("---\n - a\n - b")             # => #<Psych::Parser>
parser.handler                              # => #<Psych::TreeBuilder>
parser.handler.root                         # => #<Psych::Nodes::Stream>

Получение потока событий

recorder = Psych::Handlers::Recorder.new
parser = Psych::Parser.new(recorder)

parser.parse("---\n - a\n - b")
recorder.events # => [list of [event, args] lists]
                # event is one of: Psych::Handler::EVENTS
                # args are the arguments passed to the event

Генерация

Генератор самого низкого уровня — это событийная система. События отправляются объекту Psych::Emitter. Этот объект знает, как преобразовать события в документ YAML. Этот интерфейс следует использовать, когда формат документа известен заранее или важна скорость. См. Psych::Emitter для получения дополнительной информации.

Запись в структуру Ruby

Psych.parser.parse("--- a")       # => #<Psych::Parser>

parser.handler.first              # => #<Psych::Nodes::Stream>
parser.handler.first.to_ruby      # => ["a"]

parser.handler.root.first         # => #<Psych::Nodes::Document>
parser.handler.root.first.to_ruby # => "a"

# You can instantiate an Emitter manually
Psych::Visitors::ToRuby.new.accept(parser.handler.root.first)
# => "a"
END_OF_DOCUMENT_MARKER

Константы

DEFAULT_SNAKEYAML_VERSION
LIBYAML_VERSION

Версия libyaml, используемая Psych

VERSION

Версия Psych, которую вы используете

Публичные методы класса

dump(o) → строка yaml Показать исходный код
dump(o, options) → строка yaml
dump(o, io) → переданный объект io
dump(o, io, options) → переданный объект io
# File ext/psych/lib/psych.rb, line 505
def self.dump o, io = nil, options = {}
  if Hash === io
    options = io
    io      = nil
  end

  visitor = Psych::Visitors::YAMLTree.create options
  visitor << o
  visitor.tree.yaml io, options
end

Преобразует объект Ruby o в строку YAML. Можно передать необязательные параметры options для управления форматом вывода. Если передан объект IO, YAML будет выгружен в этот объект IO.

В настоящее время поддерживаются следующие параметры:

:indentation

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

По умолчанию: 2.

:line_width

Максимальное количество символов для переноса строки.

По умолчанию: 0 (означает «перенос на 81»).

:canonical

Записывает YAML в канонической форме (очень многословный, но строго формальный).

По умолчанию: false.

:header

Записывает %YAML [version] в начале документа.

По умолчанию: false.

Пример:

# Dump an array, get back a YAML string
Psych.dump(['a', 'b'])  # => "---\n- a\n- b\n"

# Dump an array to an IO object
Psych.dump(['a', 'b'], StringIO.new)  # => #<StringIO:0x000001009d0890>

# Dump an array with indentation set
Psych.dump(['a', ['b']], indentation: 3) # => "---\n- a\n-  - b\n"

# Dump an array to an IO with indentation set
Psych.dump(['a', ['b']], StringIO.new, indentation: 3)
dump_stream(*objects) Показать исходный код
# File ext/psych/lib/psych.rb, line 595
def self.dump_stream *objects
  visitor = Psych::Visitors::YAMLTree.create({})
  objects.each do |o|
    visitor << o
  end
  visitor.tree.yaml
end

Выгружает список объектов как отдельные документы в поток документов.

Пример:

Psych.dump_stream("foo\n  ", {}) # => "--- ! \"foo\\n  \"\n--- {}\n"
libyaml_version Показать исходный код
static VALUE libyaml_version(VALUE module)
{
    int major, minor, patch;
    VALUE list[3];

    yaml_get_version(&major, &minor, &patch);

    list[0] = INT2NUM(major);
    list[1] = INT2NUM(minor);
    list[2] = INT2NUM(patch);

    return rb_ary_new4((long)3, list);
}

Возвращает версию используемой библиотеки libyaml

load(yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false) Показать исходный код
# File ext/psych/lib/psych.rb, line 368
def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
  safe_load yaml, permitted_classes: permitted_classes,
                  permitted_symbols: permitted_symbols,
                  aliases: aliases,
                  filename: filename,
                  fallback: fallback,
                  symbolize_names: symbolize_names,
                  freeze: freeze,
                  strict_integer: strict_integer
end

Загружает yaml в структуру данных Ruby. Если предоставлено несколько документов, будет возвращен объект, содержащийся в первом документе. filename будет использоваться в сообщении об исключении, если при анализе возникнет исключение. Если yaml пуст, он возвращает указанное значение возврата fallback, которое по умолчанию равно false.

Вызывает исключение Psych::SyntaxError, когда обнаруживается синтаксическая ошибка YAML.

Пример:

Psych.load("--- a")             # => 'a'
Psych.load("---\n - a\n - b")   # => ['a', 'b']

begin
  Psych.load("--- `", filename: "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

Когда необязательный аргумент ключевого слова symbolize_names имеет истинное значение, возвращает символы для ключей в объектах Hash (по умолчанию: строки).

Psych.load("---\n foo: bar")                         # => {"foo"=>"bar"}
Psych.load("---\n foo: bar", symbolize_names: true)  # => {:foo=>"bar"}

Вызывает исключение TypeError, когда параметр `yaml` является NilClass. Этот метод похож на `safe_load`, за исключением того, что объекты `Symbol` разрешены по умолчанию.

load_file(filename, **kwargs) Показать исходный код
# File ext/psych/lib/psych.rb, line 669
def self.load_file filename, **kwargs
  File.open(filename, 'r:bom|utf-8') { |f|
    self.load f, filename: filename, **kwargs
  }
end

Загружает документ, содержащийся в filename. Возвращает YAML, содержащийся в filename, как объект Ruby, или, если файл пуст, возвращает указанное значение возврата fallback, которое по умолчанию равно false. См. load для параметров.

load_stream(yaml, filename: nil, fallback: [], **kwargs) { |to_ruby(**kwargs)| ... } Показать исходный код
# File ext/psych/lib/psych.rb, line 626
def self.load_stream yaml, filename: nil, fallback: [], **kwargs
  result = if block_given?
             parse_stream(yaml, filename: filename) do |node|
               yield node.to_ruby(**kwargs)
             end
           else
             parse_stream(yaml, filename: filename).children.map { |node| node.to_ruby(**kwargs) }
           end

  return fallback if result.is_a?(Array) && result.empty?
  result
end

Загружает несколько документов, заданных в yaml. Возвращает проанализированные документы в виде списка. Если задан блок, каждый документ будет преобразован в Ruby и передан в блок во время анализа

Пример:

Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar']

list = []
Psych.load_stream("--- foo\n...\n--- bar\n...") do |ruby|
  list << ruby
end
list # => ['foo', 'bar']
parse(yaml, filename: nil) Показать исходный код
# File ext/psych/lib/psych.rb, line 398
def self.parse yaml, filename: nil
  parse_stream(yaml, filename: filename) do |node|
    return node
  end

  false
end

Анализирует строку YAML в yaml. Возвращает Psych::Nodes::Document. filename используется в сообщении об исключении, если возникает Psych::SyntaxError.

Вызывает исключение Psych::SyntaxError, когда обнаруживается синтаксическая ошибка YAML.

Пример:

Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Document:0x00>

begin
  Psych.parse("--- `", filename: "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

См. Psych::Nodes для получения дополнительной информации об AST YAML.

parse_file(filename, fallback: false) Показать исходный код
# File ext/psych/lib/psych.rb, line 410
def self.parse_file filename, fallback: false
  result = File.open filename, 'r:bom|utf-8' do |f|
    parse f, filename: filename
  end
  result || fallback
end

Анализирует файл по адресу filename. Возвращает Psych::Nodes::Document.

Вызывает исключение Psych::SyntaxError, когда обнаруживается синтаксическая ошибка YAML.

parse_stream(yaml, filename: nil, &block) Показать исходный код
# File ext/psych/lib/psych.rb, line 452
def self.parse_stream yaml, filename: nil, &block
  if block_given?
    parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
    parser.parse yaml, filename
  else
    parser = self.parser
    parser.parse yaml, filename
    parser.handler.root
  end
end

Анализирует строку YAML в yaml. Возвращает Psych::Nodes::Stream. Этот метод может обрабатывать несколько документов YAML, содержащихся в yaml. filename используется в сообщении об исключении, если возникает Psych::SyntaxError.

Если задан блок, узел Psych::Nodes::Document будет передан в блок во время анализа.

Вызывает исключение Psych::SyntaxError, когда обнаруживается синтаксическая ошибка YAML.

Пример:

Psych.parse_stream("---\n - a\n - b") # => #<Psych::Nodes::Stream:0x00>

Psych.parse_stream("--- a\n--- b") do |node|
  node # => #<Psych::Nodes::Document:0x00>
end

begin
  Psych.parse_stream("--- `", filename: "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

Вызывает исключение TypeError, когда передается NilClass.

См. Psych::Nodes для получения дополнительной информации об AST YAML.

parser() Показать исходный код
# File ext/psych/lib/psych.rb, line 419
def self.parser
  Psych::Parser.new(TreeBuilder.new)
end

Возвращает анализатор по умолчанию

safe_dump(o) → строка yaml Показать исходный код
safe_dump(o, options) → строка yaml
safe_dump(o, io) → переданный объект io
safe_dump(o, io, options) → переданный объект io
# File ext/psych/lib/psych.rb, line 578
def self.safe_dump o, io = nil, options = {}
  if Hash === io
    options = io
    io      = nil
  end

  visitor = Psych::Visitors::RestrictedYAMLTree.create options
  visitor << o
  visitor.tree.yaml io, options
end

Безопасно выводит объект Ruby o в строку YAML. Дополнительные options могут быть переданы для управления форматом вывода. Если передается объект IO, YAML будет выведен в этот объект IO. По умолчанию разрешены только следующие классы:

  • TrueClass

  • FalseClass

  • NilClass

  • Integer

  • Float

  • String

  • Array

  • Hash

Произвольные классы могут быть разрешены путем добавления этих классов к аргументу ключевого слова permitted_classes. Они являются аддитивными. Например, для разрешения сериализации Date:

Psych.safe_dump(yaml, permitted_classes: [Date])

Теперь класс Date может быть выведен дополнительно к перечисленным выше классам.

Исключение Psych::DisallowedClass будет поднято, если объект содержит класс, отсутствующий в списке permitted_classes.

В настоящее время поддерживаются следующие параметры:

:indentation

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

По умолчанию: 2.

:line_width

Максимальное количество символов для переноса строки.

По умолчанию: 0 (что означает «перенос строки на 81»).

:canonical

Записать «каноническую» форму YAML (очень подробную, но строго формальную).

По умолчанию: false.

:header

Записать %YAML [version] в начале документа.

По умолчанию: false.

Пример:

# Dump an array, get back a YAML string
Psych.safe_dump(['a', 'b'])  # => "---\n- a\n- b\n"

# Dump an array to an IO object
Psych.safe_dump(['a', 'b'], StringIO.new)  # => #<StringIO:0x000001009d0890>

# Dump an array with indentation set
Psych.safe_dump(['a', ['b']], indentation: 3) # => "---\n- a\n-  - b\n"

# Dump an array to an IO with indentation set
Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3)
safe_load(yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false) Показать исходный код
# File ext/psych/lib/psych.rb, line 322
def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
  result = parse(yaml, filename: filename)
  return fallback unless result

  class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s),
                                             permitted_symbols.map(&:to_s))
  scanner      = ScalarScanner.new class_loader, strict_integer: strict_integer
  visitor = if aliases
              Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
            else
              Visitors::NoAliasRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
            end
  result = visitor.accept result
  result
end

Безопасно загружает строку yaml в yaml. По умолчанию разрешены только следующие классы:

  • TrueClass

  • FalseClass

  • NilClass

  • Integer

  • Float

  • String

  • Array

  • Hash

Вложенные структуры данных по умолчанию не разрешены. Произвольные классы могут быть разрешены, добавив эти классы к аргументу ключевого слова permitted_classes. Они являются аддитивными. Например, для разрешения десериализации Date:

Psych.safe_load(yaml, permitted_classes: [Date])

Теперь класс Date может быть загружен в дополнение к перечисленным выше классам.

Псевдонимы могут быть явно разрешены, изменив аргумент ключевого слова aliases. Например:

x = []
x << x
yaml = Psych.dump x
Psych.safe_load yaml               # => raises an exception
Psych.safe_load yaml, aliases: true # => loads the aliases

Исключение Psych::DisallowedClass будет поднято, если yaml содержит класс, отсутствующий в списке permitted_classes.

Исключение Psych::AliasesNotEnabled будет поднято, если yaml содержит псевдонимы, но аргумент ключевого слова aliases установлен в false.

filename будет использоваться в сообщении об ошибке, если при разборе возникнет какая-либо ошибка.

Если необязательный аргумент ключевого слова symbolize_names установлен в значение true, возвращаются символы для ключей в объектах Hash (по умолчанию: строки).

Psych.safe_load("---\n foo: bar")                         # => {"foo"=>"bar"}
Psych.safe_load("---\n foo: bar", symbolize_names: true)  # => {:foo=>"bar"}
safe_load_file(filename, **kwargs) Показать исходный код
# File ext/psych/lib/psych.rb, line 658
def self.safe_load_file filename, **kwargs
  File.open(filename, 'r:bom|utf-8') { |f|
    self.safe_load f, filename: filename, **kwargs
  }
end

Безопасно загружает документ, содержащийся в filename. Возвращает содержащийся в filename yaml в виде объекта Ruby, или, если файл пуст, возвращает указанное значение возврата fallback, которое по умолчанию равно false. См. safe_load для параметров.

to_json(object) Показать исходный код
# File ext/psych/lib/psych.rb, line 605
def self.to_json object
  visitor = Psych::Visitors::JSONTree.create
  visitor << object
  visitor.tree.yaml
end

Вывести объект Ruby object в строку JSON.

unsafe_load(yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false) Показать исходный код
# File ext/psych/lib/psych.rb, line 271
def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false
  result = parse(yaml, filename: filename)
  return fallback unless result
  result.to_ruby(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer)
end

Загрузка yaml в структуру данных Ruby. Если предоставлено несколько документов, будет возвращен объект, содержащийся в первом документе. filename будет использоваться в сообщении об ошибке, если при разборе возникнет какая-либо ошибка. Если yaml пусто, возвращает указанное значение возврата fallback, которое по умолчанию равно false.

Выбрасывает исключение Psych::SyntaxError при обнаружении синтаксической ошибки YAML.

Пример:

Psych.unsafe_load("--- a")             # => 'a'
Psych.unsafe_load("---\n - a\n - b")   # => ['a', 'b']

begin
  Psych.unsafe_load("--- `", filename: "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

Если необязательный аргумент ключевого слова symbolize_names установлен в значение true, возвращаются символы для ключей в объектах Hash (по умолчанию: строки).

Psych.unsafe_load("---\n foo: bar")                         # => {"foo"=>"bar"}
Psych.unsafe_load("---\n foo: bar", symbolize_names: true)  # => {:foo=>"bar"}

Выбрасывает исключение TypeError, когда параметр ‘yaml` равен NilClass

ПРИМЕЧАНИЕ. Этот метод *не следует* использовать для разбора недоверенных документов, таких как документы YAML, которые предоставляются через пользовательский ввод. Вместо этого используйте метод load или метод safe_load.

unsafe_load_file(filename, **kwargs) Показать исходный код
# File ext/psych/lib/psych.rb, line 647
def self.unsafe_load_file filename, **kwargs
  File.open(filename, 'r:bom|utf-8') { |f|
    self.unsafe_load f, filename: filename, **kwargs
  }
end

Загружает документ, содержащийся в filename. Возвращает содержащийся в filename yaml в виде объекта Ruby, или, если файл пуст, возвращает указанное значение возврата fallback, которое по умолчанию равно false.

ПРИМЕЧАНИЕ. Этот метод *не следует* использовать для разбора недоверенных документов, таких как документы YAML, которые предоставляются через пользовательский ввод. Вместо этого используйте метод safe_load_file.

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API