[前][次][番号順一覧][スレッド一覧]

ruby-changes:22904

From: tenderlove <ko1@a...>
Date: Fri, 9 Mar 2012 06:22:07 +0900 (JST)
Subject: [ruby-changes:22904] tenderlove:r34953 (trunk): * ext/psych/lib/psych.rb (parse_stream, load_stream): if a block is

tenderlove	2012-03-09 06:21:52 +0900 (Fri, 09 Mar 2012)

  New Revision: 34953

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=34953

  Log:
    * 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.

  Added directories:
    trunk/ext/psych/lib/psych/handlers/
  Added files:
    trunk/ext/psych/lib/psych/handlers/document_stream.rb
  Modified files:
    trunk/ChangeLog
    trunk/ext/psych/lib/psych.rb
    trunk/test/psych/test_stream.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 34952)
+++ ChangeLog	(revision 34953)
@@ -1,3 +1,14 @@
+Fri Mar  9 06:17:05 2012  Aaron Patterson <aaron@t...>
+
+	* 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@r...>
 
 	* enumerator.c (lazy_initialize, enumerable_lazy): no additional
Index: ext/psych/lib/psych/handlers/document_stream.rb
===================================================================
--- ext/psych/lib/psych/handlers/document_stream.rb	(revision 0)
+++ ext/psych/lib/psych/handlers/document_stream.rb	(revision 34953)
@@ -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
Index: ext/psych/lib/psych.rb
===================================================================
--- ext/psych/lib/psych.rb	(revision 34952)
+++ ext/psych/lib/psych.rb	(revision 34953)
@@ -13,6 +13,7 @@
 require 'psych/stream'
 require 'psych/json/tree_builder'
 require 'psych/json/stream'
+require 'psych/handlers/document_stream'
 
 ###
 # = Overview
@@ -173,12 +174,19 @@
   # +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 @@
   #   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 @@
 
   ###
   # 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
 
   ###
Index: test/psych/test_stream.rb
===================================================================
--- test/psych/test_stream.rb	(revision 34952)
+++ test/psych/test_stream.rb	(revision 34953)
@@ -2,6 +2,40 @@
 
 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)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]