module Psych

Overview

Psych is aYAML parser and emitter.Psych leverages libyaml [Home page:pyyaml.org/wiki/LibYAML] or [git repo:github.com/yaml/libyaml] for itsYAML parsing and emitting capabilities. In addition to wrapping libyaml,Psych also knows how to serialize and de-serialize most Ruby objects to and from theYAML format.

I NEED TO PARSE OR EMITYAML RIGHT NOW!

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

Got more time on your hands? Keep on reading!

YAML Parsing

Psych provides a range of interfaces for parsing aYAML document ranging from low level to high level, depending on your parsing needs. At the lowest level, is an event based parser. Mid level is access to the rawYAML AST, and at the highest level is the ability to unmarshalYAML to Ruby objects.

YAML Emitting

Psych provides a range of interfaces ranging from low to high level for producingYAML documents. Very similar to theYAML parsing interfaces,Psych provides at the lowest level, an event based system, mid-level is building aYAML AST, and the highest level is converting a Ruby object straight to aYAML document.

High-level API

Parsing

The high levelYAML parser provided byPsych simply takesYAML as input and returns a Ruby data structure. For information on using the high level parser seePsych.load

Reading from a string

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

Reading from a file

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

Exception handling

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

Emitting

The high level emitter has the easiest interface.Psych simply takes a Ruby data structure and converts it to aYAML document. SeePsych.dump for more information on dumping a Ruby data structure.

Writing to a string

# Dump an array, get back a YAML stringPsych.dump(['a','b'])# => "---\n- a\n- b\n"# Dump an array to an IO objectPsych.dump(['a','b'],StringIO.new)# => #<StringIO:0x000001009d0890># Dump an array with indentation setPsych.dump(['a', ['b']],:indentation=>3)# => "---\n- a\n-  - b\n"# Dump an array to an IO with indentation setPsych.dump(['a', ['b']],StringIO.new,:indentation=>3)

Writing to a file

Currently there is no direct API for dumping Ruby structure to file:

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

Mid-level API

Parsing

Psych provides access to an AST produced from parsing aYAML document. This tree is built using thePsych::Parser andPsych::TreeBuilder. The AST can be examined and manipulated freely. Please seePsych::parse_stream,Psych::Nodes, andPsych::Nodes::Node for more information on dealing withYAML syntax trees.

Reading from a string

# Returns Psych::Nodes::StreamPsych.parse_stream("---\n - a\n - b")# Returns Psych::Nodes::DocumentPsych.parse("---\n - a\n - b")

Reading from a file

# Returns Psych::Nodes::StreamPsych.parse_stream(File.read('database.yml'))# Returns Psych::Nodes::DocumentPsych.parse_file('database.yml')

Exception handling

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

Emitting

At the mid level is building an AST. This AST is exactly the same as the AST used when parsing aYAML document. Users can build an AST by hand and the AST knows how to emit itself as aYAML document. SeePsych::Nodes,Psych::Nodes::Node, andPsych::TreeBuilder for more information on building aYAML AST.

Writing to a string

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

Writing to a file

# 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

Low-level API

Parsing

The lowest level parser should be used when theYAML input is already known, and the developer does not want to pay the price of building an AST or automatic detection and conversion to Ruby objects. SeePsych::Parser for more information on using the event based parser.

Reading toPsych::Nodes::Stream structure

parser =Psych::Parser.new(TreeBuilder.new)# => #<Psych::Parser>parser =Psych.parser# it's an alias for the aboveparser.parse("---\n - a\n - b")# => #<Psych::Parser>parser.handler# => #<Psych::TreeBuilder>parser.handler.root# => #<Psych::Nodes::Stream>

Receiving an events stream

recorder =Psych::Handlers::Recorder.newparser =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

Emitting

The lowest level emitter is an event based system. Events are sent to aPsych::Emitter object. That object knows how to convert the events to aYAML document. This interface should be used when document format is known in advance or speed is a concern. SeePsych::Emitter for more information.

Writing to a Ruby structure

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 manuallyPsych::Visitors::ToRuby.new.accept(parser.handler.root.first)# => "a"

Constants

DEFAULT_SNAKEYAML_VERSION
LIBYAML_VERSION

The version of libyamlPsych is using

VERSION

The version ofPsych you are using

Public Class Methods

Source
# File ext/psych/lib/psych.rb, line 514defself.dumpo,io =nil,options = {}ifHash===iooptions =ioio      =nilendvisitor =Psych::Visitors::YAMLTree.createoptionsvisitor<<ovisitor.tree.yamlio,optionsend

Dump Ruby objecto to aYAML string. Optionaloptions may be passed in to control the output format. If anIO object is passed in, theYAML will be dumped to thatIO object.

Currently supported options are:

:indentation

Number of space characters used to indent. Acceptable value should be in0..9 range, otherwise option is ignored.

Default:2.

:line_width

Max character to wrap line at. For unlimited line width use-1.

Default:0 (meaning “wrap at 81”).

:canonical

Write “canonical”YAML form (very verbose, yet strictly formal).

Default:false.

:header

Write%YAML [version] at the beginning of document.

Default:false.

:stringify_names

Dump symbol keys inHash objects as string.

Default:false.

Example:

# Dump an array, get back a YAML stringPsych.dump(['a','b'])# => "---\n- a\n- b\n"# Dump an array to an IO objectPsych.dump(['a','b'],StringIO.new)# => #<StringIO:0x000001009d0890># Dump an array with indentation setPsych.dump(['a', ['b']],indentation:3)# => "---\n- a\n-  - b\n"# Dump an array to an IO with indentation setPsych.dump(['a', ['b']],StringIO.new,indentation:3)# Dump hash with symbol keys as stringPsych.dump({a:"b"},stringify_names:true)# => "---\na: b\n"
Source
# File ext/psych/lib/psych.rb, line 612defself.dump_stream*objectsvisitor =Psych::Visitors::YAMLTree.create({})objects.eachdo|o|visitor<<oendvisitor.tree.yamlend

Dump a list of objects as separate documents to a document stream.

Example:

Psych.dump_stream("foo\n  ", {})# => "--- ! \"foo\\n  \"\n--- {}\n"
Source
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);}

Returns the version of libyaml being used

Source
# File ext/psych/lib/psych.rb, line 369defself.loadyaml,permitted_classes: [Symbol],permitted_symbols: [],aliases:false,filename:nil,fallback:nil,symbolize_names:false,freeze:false,strict_integer:falsesafe_loadyaml,permitted_classes:permitted_classes,permitted_symbols:permitted_symbols,aliases:aliases,filename:filename,fallback:fallback,symbolize_names:symbolize_names,freeze:freeze,strict_integer:strict_integerend

Loadyaml in to a Ruby data structure. If multiple documents are provided, the object contained in the first document will be returned.filename will be used in the exception message if any exception is raised while parsing. Ifyaml is empty, it returns the specifiedfallback return value, which defaults tonil.

Raises aPsych::SyntaxError when aYAML syntax error is detected.

Example:

Psych.load("--- a")# => 'a'Psych.load("---\n - a\n - b")# => ['a', 'b']beginPsych.load("--- `",filename:"file.txt")rescuePsych::SyntaxError=>exex.file# => 'file.txt'ex.message# => "(file.txt): found character that cannot start any token"end

When the optionalsymbolize_names keyword argument is set to a true value, returns symbols for keys inHash objects (default: strings).

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

Raises aTypeError when ‘yaml` parameter isNilClass. This method is similar to `safe_load` except that `Symbol` objects are allowed by default.

Source
# File ext/psych/lib/psych.rb, line 715defself.load_filefilename,**kwargsFile.open(filename,'r:bom|utf-8') {|f|self.loadf,filename:filename,**kwargs  }end

Loads the document contained infilename. Returns the yaml contained infilename as a Ruby object, or if the file is empty, it returns the specifiedfallback return value, which defaults tonil. See load for options.

Source
# File ext/psych/lib/psych.rb, line 643defself.load_streamyaml,filename:nil,fallback: [],**kwargsresult =ifblock_given?parse_stream(yaml,filename:filename)do|node|yieldnode.to_ruby(**kwargs)endelseparse_stream(yaml,filename:filename).children.map {|node|node.to_ruby(**kwargs) }endreturnfallbackifresult.is_a?(Array)&&result.empty?resultend

Load multiple documents given inyaml. Returns the parsed documents as a list. If a block is given, each document will be converted to Ruby and passed to the block during parsing

Example:

Psych.load_stream("--- foo\n...\n--- bar\n...")# => ['foo', 'bar']list = []Psych.load_stream("--- foo\n...\n--- bar\n...")do|ruby|list<<rubyendlist# => ['foo', 'bar']
Source
# File ext/psych/lib/psych.rb, line 399defself.parseyaml,filename:nilparse_stream(yaml,filename:filename)do|node|returnnodeendfalseend

Parse aYAML string inyaml. Returns thePsych::Nodes::Document.filename is used in the exception message if aPsych::SyntaxError is raised.

Raises aPsych::SyntaxError when aYAML syntax error is detected.

Example:

Psych.parse("---\n - a\n - b")# => #<Psych::Nodes::Document:0x00>beginPsych.parse("--- `",filename:"file.txt")rescuePsych::SyntaxError=>exex.file# => 'file.txt'ex.message# => "(file.txt): found character that cannot start any token"end

SeePsych::Nodes for more information aboutYAML AST.

Source
# File ext/psych/lib/psych.rb, line 411defself.parse_filefilename,fallback:falseresult =File.openfilename,'r:bom|utf-8'do|f|parsef,filename:filenameendresult||fallbackend

Parse a file atfilename. Returns thePsych::Nodes::Document.

Raises aPsych::SyntaxError when aYAML syntax error is detected.

Source
# File ext/psych/lib/psych.rb, line 453defself.parse_streamyaml,filename:nil,&blockifblock_given?parser =Psych::Parser.new(Handlers::DocumentStream.new(&block))parser.parseyaml,filenameelseparser =self.parserparser.parseyaml,filenameparser.handler.rootendend

Parse aYAML string inyaml. Returns thePsych::Nodes::Stream. This method can handle multipleYAML documents contained inyaml.filename is used in the exception message if aPsych::SyntaxError is raised.

If a block is given, aPsych::Nodes::Document node will be yielded to the block as it’s being parsed.

Raises aPsych::SyntaxError when aYAML syntax error is detected.

Example:

Psych.parse_stream("---\n - a\n - b")# => #<Psych::Nodes::Stream:0x00>Psych.parse_stream("--- a\n--- b")do|node|node# => #<Psych::Nodes::Document:0x00>endbeginPsych.parse_stream("--- `",filename:"file.txt")rescuePsych::SyntaxError=>exex.file# => 'file.txt'ex.message# => "(file.txt): found character that cannot start any token"end

Raises aTypeError whenNilClass is passed.

SeePsych::Nodes for more information aboutYAML AST.

Source
# File ext/psych/lib/psych.rb, line 420defself.parserPsych::Parser.new(TreeBuilder.new)end

Returns a default parser

Source
# File ext/psych/lib/psych.rb, line 595defself.safe_dumpo,io =nil,options = {}ifHash===iooptions =ioio      =nilendvisitor =Psych::Visitors::RestrictedYAMLTree.createoptionsvisitor<<ovisitor.tree.yamlio,optionsend

Safely dump Ruby objecto to aYAML string. Optionaloptions may be passed in to control the output format. If anIO object is passed in, theYAML will be dumped to thatIO object. By default, only the following classes are allowed to be serialized:

Arbitrary classes can be allowed by adding those classes to thepermitted_classes keyword argument. They are additive. For example, to allowDate serialization:

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

Now theDate class can be dumped in addition to the classes listed above.

APsych::DisallowedClass exception will be raised if the object contains a class that isn’t in thepermitted_classes list.

Currently supported options are:

:indentation

Number of space characters used to indent. Acceptable value should be in0..9 range, otherwise option is ignored.

Default:2.

:line_width

Max character to wrap line at. For unlimited line width use-1.

Default:0 (meaning “wrap at 81”).

:canonical

Write “canonical”YAML form (very verbose, yet strictly formal).

Default:false.

:header

Write%YAML [version] at the beginning of document.

Default:false.

:stringify_names

Dump symbol keys inHash objects as string.

Default:false.

Example:

# Dump an array, get back a YAML stringPsych.safe_dump(['a','b'])# => "---\n- a\n- b\n"# Dump an array to an IO objectPsych.safe_dump(['a','b'],StringIO.new)# => #<StringIO:0x000001009d0890># Dump an array with indentation setPsych.safe_dump(['a', ['b']],indentation:3)# => "---\n- a\n-  - b\n"# Dump an array to an IO with indentation setPsych.safe_dump(['a', ['b']],StringIO.new,indentation:3)# Dump hash with symbol keys as stringPsych.dump({a:"b"},stringify_names:true)# => "---\na: b\n"
Source
# File ext/psych/lib/psych.rb, line 323defself.safe_loadyaml,permitted_classes: [],permitted_symbols: [],aliases:false,filename:nil,fallback:nil,symbolize_names:false,freeze:false,strict_integer:falseresult =parse(yaml,filename:filename)returnfallbackunlessresultclass_loader =ClassLoader::Restricted.new(permitted_classes.map(&:to_s),permitted_symbols.map(&:to_s))scanner      =ScalarScanner.newclass_loader,strict_integer:strict_integervisitor =ifaliasesVisitors::ToRuby.newscanner,class_loader,symbolize_names:symbolize_names,freeze:freezeelseVisitors::NoAliasRuby.newscanner,class_loader,symbolize_names:symbolize_names,freeze:freezeendresult =visitor.acceptresultresultend

Safely load the yaml string inyaml. By default, only the following classes are allowed to be deserialized:

Recursive data structures are not allowed by default. Arbitrary classes can be allowed by adding those classes to thepermitted_classes keyword argument. They are additive. For example, to allowDate deserialization:

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

Now theDate class can be loaded in addition to the classes listed above.

Aliases can be explicitly allowed by changing thealiases keyword argument. For example:

x = []x<<xyaml =Psych.dumpxPsych.safe_loadyaml# => raises an exceptionPsych.safe_loadyaml,aliases:true# => loads the aliases

APsych::DisallowedClass exception will be raised if the yaml contains a class that isn’t in thepermitted_classes list.

APsych::AliasesNotEnabled exception will be raised if the yaml contains aliases but thealiases keyword argument is set to false.

filename will be used in the exception message if any exception is raised while parsing.

When the optionalsymbolize_names keyword argument is set to a true value, returns symbols for keys inHash objects (default: strings).

Psych.safe_load("---\n foo: bar")# => {"foo"=>"bar"}Psych.safe_load("---\n foo: bar",symbolize_names:true)# => {:foo=>"bar"}
Source
# File ext/psych/lib/psych.rb, line 704defself.safe_load_filefilename,**kwargsFile.open(filename,'r:bom|utf-8') {|f|self.safe_loadf,filename:filename,**kwargs  }end

Safely loads the document contained infilename. Returns the yaml contained infilename as a Ruby object, or if the file is empty, it returns the specifiedfallback return value, which defaults tonil. Seesafe_load for options.

Source
# File ext/psych/lib/psych.rb, line 670defself.safe_load_streamyaml,filename:nil,permitted_classes: [],aliases:falsedocuments =parse_stream(yaml,filename:filename).children.mapdo|child|stream =Psych::Nodes::Stream.newstream.children<<childsafe_load(stream.to_yaml,permitted_classes:permitted_classes,aliases:aliases)endifblock_given?documents.each {|doc|yielddoc }nilelsedocumentsendend

Load multiple documents given inyaml. Returns the parsed documents as a list.

Example:

Psych.safe_load_stream("--- foo\n...\n--- bar\n...")# => ['foo', 'bar']list = []Psych.safe_load_stream("--- foo\n...\n--- bar\n...")do|ruby|list<<rubyendlist# => ['foo', 'bar']
Source
# File ext/psych/lib/psych.rb, line 622defself.to_jsonobjectvisitor =Psych::Visitors::JSONTree.createvisitor<<objectvisitor.tree.yamlend

Dump Rubyobject to aJSON string.

Source
# File ext/psych/lib/psych.rb, line 272defself.unsafe_loadyaml,filename:nil,fallback:false,symbolize_names:false,freeze:false,strict_integer:falseresult =parse(yaml,filename:filename)returnfallbackunlessresultresult.to_ruby(symbolize_names:symbolize_names,freeze:freeze,strict_integer:strict_integer)end

Loadyaml in to a Ruby data structure. If multiple documents are provided, the object contained in the first document will be returned.filename will be used in the exception message if any exception is raised while parsing. Ifyaml is empty, it returns the specifiedfallback return value, which defaults tofalse.

Raises aPsych::SyntaxError when aYAML syntax error is detected.

Example:

Psych.unsafe_load("--- a")# => 'a'Psych.unsafe_load("---\n - a\n - b")# => ['a', 'b']beginPsych.unsafe_load("--- `",filename:"file.txt")rescuePsych::SyntaxError=>exex.file# => 'file.txt'ex.message# => "(file.txt): found character that cannot start any token"end

When the optionalsymbolize_names keyword argument is set to a true value, returns symbols for keys inHash objects (default: strings).

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

Raises aTypeError when ‘yaml` parameter isNilClass

NOTE: This method *should not* be used to parse untrusted documents, such asYAML documents that are supplied via user input. Instead, please use the load method or thesafe_load method.

Source
# File ext/psych/lib/psych.rb, line 693defself.unsafe_load_filefilename,**kwargsFile.open(filename,'r:bom|utf-8') {|f|self.unsafe_loadf,filename:filename,**kwargs  }end

Load the document contained infilename. Returns the yaml contained infilename as a Ruby object, or if the file is empty, it returns the specifiedfallback return value, which defaults tofalse.

NOTE: This method *should not* be used to parse untrusted documents, such asYAML documents that are supplied via user input. Instead, please use thesafe_load_file method.