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
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:
:indentationNumber of space characters used to indent. Acceptable value should be in
0..9range, otherwise option is ignored.Default:
2.:line_widthMax character to wrap line at. For unlimited line width use
-1.Default:
0(meaning “wrap at 81”).:canonicalWrite “canonical”
YAMLform (very verbose, yet strictly formal).Default:
false.:headerWrite
%YAML [version]at the beginning of document.Default:
false.:stringify_namesDump symbol keys in
Hashobjects 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:
:indentationNumber of space characters used to indent. Acceptable value should be in
0..9range, otherwise option is ignored.Default:
2.:line_widthMax character to wrap line at. For unlimited line width use
-1.Default:
0(meaning “wrap at 81”).:canonicalWrite “canonical”
YAMLform (very verbose, yet strictly formal).Default:
false.:headerWrite
%YAML [version]at the beginning of document.Default:
false.:stringify_namesDump symbol keys in
Hashobjects 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.