Spec-Zone.ru › Ruby 2.5

модуль Psych

Обзор

Psych — это парсер и генератор YAML. Psych использует libyaml [Главная страница: pyyaml.org/wiki/LibYAML] или [Репозиторий HG: bitbucket.org/xi/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, а на самом высоком уровне — возможность распаковки YAML в объекты Ruby.

Генерация YAML

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

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

Парсинг

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

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

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

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

Psych.load_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

Генерация

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

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

# 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 можно свободно исследовать и изменять. Для получения дополнительной информации о работе с деревьями синтаксиса YAML см. ::parse_stream, Psych::Nodes и Psych::Nodes::Node.

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

# 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. Для получения дополнительной информации о создании дерева абстрактного синтаксиса YAML см. Psych::Nodes, Psych::Nodes::Node и Psych::TreeBuilder.

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

# 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"

Константы

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 433
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.

Пример:

# 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 450
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((long)major);
    list[1] = INT2NUM((long)minor);
    list[2] = INT2NUM((long)patch);

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

Возвращает версию используемого libyaml.

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

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

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

Пример:

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

begin
  Psych.load("--- `", "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.load("---\n foo: bar")                         # => {"foo"=>"bar"}
Psych.load("---\n foo: bar", symbolize_names: true)  # => {:foo=>"bar"}
load_file(filename, fallback: false) Показать исходный код
# File ext/psych/lib/psych.rb, line 495
def self.load_file filename, fallback: false
  File.open(filename, 'r:bom|utf-8') { |f|
    self.load f, filename, fallback: FALLBACK.new(fallback)
  }
end

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

load_stream(yaml, filename = nil) { |to_ruby| ... } Показать исходный код
# File ext/psych/lib/psych.rb, line 481
def self.load_stream yaml, filename = nil
  if block_given?
    parse_stream(yaml, filename) do |node|
      yield node.to_ruby
    end
  else
    parse_stream(yaml, filename).children.map { |child| child.to_ruby }
  end
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, fallback: false) Показать исходный код
# File ext/psych/lib/psych.rb, line 348
def self.parse yaml, filename = nil, fallback: false
  parse_stream(yaml, filename) do |node|
    return node
  end
  fallback
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("--- `", "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

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

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

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

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

parse_stream(yaml, filename = nil, &block) Показать исходный код
# File ext/psych/lib/psych.rb, line 398
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("--- `", "file.txt")
rescue Psych::SyntaxError => ex
  ex.file    # => 'file.txt'
  ex.message # => "(file.txt): found character that cannot start any token"
end

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

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

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

safe_load(yaml, whitelist_classes = [], whitelist_symbols = [], aliases = false, filename = nil, symbolize_names: false) Показать исходный код
# File ext/psych/lib/psych.rb, line 312
def self.safe_load yaml, whitelist_classes = [], whitelist_symbols = [], aliases = false, filename = nil, symbolize_names: false
  result = parse(yaml, filename)
  return unless result

  class_loader = ClassLoader::Restricted.new(whitelist_classes.map(&:to_s),
                                             whitelist_symbols.map(&:to_s))
  scanner      = ScalarScanner.new class_loader
  if aliases
    visitor = Visitors::ToRuby.new scanner, class_loader
  else
    visitor = Visitors::NoAliasRuby.new scanner, class_loader
  end
  result = visitor.accept result
  symbolize_names!(result) if symbolize_names
  result
end

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

  • TrueClass

  • FalseClass

  • NilClass

  • Numeric

  • String

  • Array

  • Hash

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

Psych.safe_load(yaml, [Date])

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

Псевдонимы можно явно разрешить, изменив параметр aliases. Например:

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

Исключение Psych::DisallowedClass будет выброшено, если yaml содержит класс, который не указан в списке разрешенных.

Исключение Psych::BadAlias будет выброшено, если 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"}
to_json(object) Показать исходный код
# File ext/psych/lib/psych.rb, line 460
def self.to_json object
  visitor = Psych::Visitors::JSONTree.create
  visitor << object
  visitor.tree.yaml
end

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

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

Spec-Zone.ru

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