summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authortenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-08 21:21:52 +0000
committertenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-08 21:21:52 +0000
commita2e3de1b3f876dd9b14fa3a6291a202719405382 (patch)
treec12747216e04ca2002016dfc9bdb88600b3cdf85 /ext
parente7d4e659a070f6e188f3924bd8efb65e6919d2ef (diff)
* 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
Diffstat (limited to 'ext')
-rw-r--r--ext/psych/lib/psych.rb40
-rw-r--r--ext/psych/lib/psych/handlers/document_stream.rb22
2 files changed, 56 insertions, 6 deletions
diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb
index cb5c4a5cf3..69f3a7c1fe 100644
--- a/ext/psych/lib/psych.rb
+++ b/ext/psych/lib/psych.rb
@@ -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
###
diff --git a/ext/psych/lib/psych/handlers/document_stream.rb b/ext/psych/lib/psych/handlers/document_stream.rb
new file mode 100644
index 0000000000..e429993c1c
--- /dev/null
+++ b/ext/psych/lib/psych/handlers/document_stream.rb
@@ -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