1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/psych/lib/psych.rb (parse_stream, load_stream): if a block is

given, documents will be yielded to the block as they are parsed.
  [ruby-core:42404] [Bug #5978]

* ext/psych/lib/psych/handlers/document_stream.rb: add a handler that
  yields documents as they are parsed

* test/psych/test_stream.rb: corresponding tests.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34953 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tenderlove 2012-03-08 21:21:52 +00:00
parent e7d4e659a0
commit a2e3de1b3f
4 changed files with 101 additions and 6 deletions

View file

@ -1,3 +1,14 @@
Fri Mar 9 06:17:05 2012 Aaron Patterson <aaron@tenderlovemaking.com>
* ext/psych/lib/psych.rb (parse_stream, load_stream): if a block is
given, documents will be yielded to the block as they are parsed.
[ruby-core:42404] [Bug #5978]
* ext/psych/lib/psych/handlers/document_stream.rb: add a handler that
yields documents as they are parsed
* test/psych/test_stream.rb: corresponding tests.
Fri Mar 9 00:35:03 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* enumerator.c (lazy_initialize, enumerable_lazy): no additional

View file

@ -13,6 +13,7 @@ require 'psych/deprecated'
require 'psych/stream'
require 'psych/json/tree_builder'
require 'psych/json/stream'
require 'psych/handlers/document_stream'
###
# = Overview
@ -173,12 +174,19 @@ module Psych
# +filename+ is used in the exception message if a Psych::SyntaxError is
# raised.
#
# If a block is given, a Psych::Nodes::Document node will be yielded to the
# block as it's being parsed.
#
# Raises a Psych::SyntaxError when a YAML 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>
# end
#
# begin
# Psych.parse_stream("--- `", "file.txt")
# rescue Psych::SyntaxError => ex
@ -187,10 +195,15 @@ module Psych
# end
#
# See Psych::Nodes for more information about YAML AST.
def self.parse_stream yaml, filename = nil
parser = self.parser
parser.parse yaml, filename
parser.handler.root
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
###
@ -252,12 +265,27 @@ module Psych
###
# Load multiple documents given in +yaml+. Returns the parsed documents
# as a list. For example:
# 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 << ruby
# end
# list # => ['foo', 'bar']
#
def self.load_stream yaml, filename = nil
parse_stream(yaml, filename).children.map { |child| child.to_ruby }
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
###

View file

@ -0,0 +1,22 @@
require 'psych/tree_builder'
module Psych
module Handlers
class DocumentStream < Psych::TreeBuilder # :nodoc:
def initialize &block
super
@block = block
end
def start_document version, tag_directives, implicit
n = Nodes::Document.new version, tag_directives, implicit
push n
end
def end_document implicit_end = !streaming?
@last.implicit_end = implicit_end
@block.call pop
end
end
end
end

View file

@ -2,6 +2,40 @@ require 'psych/helper'
module Psych
class TestStream < TestCase
def test_parse_stream_yields_documents
list = []
Psych.parse_stream("--- foo\n...\n--- bar") do |doc|
list << doc.to_ruby
end
assert_equal %w{ foo bar }, list
end
def test_parse_stream_break
list = []
Psych.parse_stream("--- foo\n...\n--- `") do |doc|
list << doc.to_ruby
break
end
assert_equal %w{ foo }, list
end
def test_load_stream_yields_documents
list = []
Psych.load_stream("--- foo\n...\n--- bar") do |ruby|
list << ruby
end
assert_equal %w{ foo bar }, list
end
def test_load_stream_break
list = []
Psych.load_stream("--- foo\n...\n--- `") do |ruby|
list << ruby
break
end
assert_equal %w{ foo }, list
end
def test_explicit_documents
io = StringIO.new
stream = Psych::Stream.new(io)