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

ruby-changes:18600

From: tenderlove <ko1@a...>
Date: Sat, 22 Jan 2011 04:12:01 +0900 (JST)
Subject: [ruby-changes:18600] Ruby:r30624 (trunk): * ext/psych/lib/psych/nodes/node.rb: Make Psych::Nodes::Node

tenderlove	2011-01-22 04:11:53 +0900 (Sat, 22 Jan 2011)

  New Revision: 30624

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

  Log:
    * ext/psych/lib/psych/nodes/node.rb: Make Psych::Nodes::Node
      enumerable.
    * ext/psych/lib/psych/visitors/depth_first.rb: Add a depth-first
      visitor to enumerate over a YAML AST in a depth-first fashion
    * test/psych/nodes/test_enumerable.rb: test for enumerating nodes
    * test/psych/visitors/test_depth_first.rb: test for depth-first
      visitor

  Added directories:
    trunk/test/psych/nodes/
  Added files:
    trunk/ext/psych/lib/psych/visitors/depth_first.rb
    trunk/test/psych/nodes/test_enumerable.rb
    trunk/test/psych/visitors/test_depth_first.rb
  Modified files:
    trunk/ChangeLog
    trunk/ext/psych/lib/psych/nodes/node.rb
    trunk/ext/psych/lib/psych/visitors.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 30623)
+++ ChangeLog	(revision 30624)
@@ -1,3 +1,16 @@
+Sat Jan 22 04:09:22 2011  Aaron Patterson <aaron@t...>
+
+	* ext/psych/lib/psych/nodes/node.rb: Make Psych::Nodes::Node
+	  enumerable.
+
+	* ext/psych/lib/psych/visitors/depth_first.rb: Add a depth-first
+	  visitor to enumerate over a YAML AST in a depth-first fashion
+
+	* test/psych/nodes/test_enumerable.rb: test for enumerating nodes
+
+	* test/psych/visitors/test_depth_first.rb: test for depth-first
+	  visitor
+
 Sat Jan 22 00:53:42 2011  Tanaka Akira  <akr@f...>
 
 	* vm_core.h: parenthesize macro arguments.
Index: ext/psych/lib/psych/visitors/depth_first.rb
===================================================================
--- ext/psych/lib/psych/visitors/depth_first.rb	(revision 0)
+++ ext/psych/lib/psych/visitors/depth_first.rb	(revision 30624)
@@ -0,0 +1,26 @@
+module Psych
+  module Visitors
+    class DepthFirst < Psych::Visitors::Visitor
+      def initialize block
+        @block = block
+      end
+
+      private
+
+      def nary o
+        o.children.each { |x| visit x }
+        @block.call o
+      end
+      alias :visit_Psych_Nodes_Stream   :nary
+      alias :visit_Psych_Nodes_Document :nary
+      alias :visit_Psych_Nodes_Sequence :nary
+      alias :visit_Psych_Nodes_Mapping  :nary
+
+      def terminal o
+        @block.call o
+      end
+      alias :visit_Psych_Nodes_Scalar :terminal
+      alias :visit_Psych_Nodes_Alias  :terminal
+    end
+  end
+end
Index: ext/psych/lib/psych/visitors.rb
===================================================================
--- ext/psych/lib/psych/visitors.rb	(revision 30623)
+++ ext/psych/lib/psych/visitors.rb	(revision 30624)
@@ -3,3 +3,4 @@
 require 'psych/visitors/emitter'
 require 'psych/visitors/yaml_tree'
 require 'psych/visitors/json_tree'
+require 'psych/visitors/depth_first'
Index: ext/psych/lib/psych/nodes/node.rb
===================================================================
--- ext/psych/lib/psych/nodes/node.rb	(revision 30623)
+++ ext/psych/lib/psych/nodes/node.rb	(revision 30624)
@@ -6,6 +6,8 @@
     # The base class for any Node in a YAML parse tree.  This class should
     # never be instantiated.
     class Node
+      include Enumerable
+
       # The children of this node
       attr_reader :children
 
@@ -18,6 +20,14 @@
       end
 
       ###
+      # Iterate over each node in the tree. Yields each node to +block+ depth
+      # first.
+      def each &block
+        return enum_for :each unless block_given?
+        Visitors::DepthFirst.new(block).accept self
+      end
+
+      ###
       # Convert this node to Ruby.
       #
       # See also Psych::Visitors::ToRuby
Index: test/psych/nodes/test_enumerable.rb
===================================================================
--- test/psych/nodes/test_enumerable.rb	(revision 0)
+++ test/psych/nodes/test_enumerable.rb	(revision 30624)
@@ -0,0 +1,43 @@
+require_relative '../helper'
+
+module Psych
+  module Nodes
+    class TestEnumerable < TestCase
+      def test_includes_enumerable
+        yaml = '--- hello'
+        assert_equal 3, Psych.parse_stream(yaml).to_a.length
+      end
+
+      def test_returns_enumerator
+        yaml = '--- hello'
+        assert_equal 3, Psych.parse_stream(yaml).each.map { |x| x }.length
+      end
+
+      def test_scalar
+        assert_equal 3, calls('--- hello').length
+      end
+
+      def test_sequence
+        assert_equal 4, calls("---\n- hello").length
+      end
+
+      def test_mapping
+        assert_equal 5, calls("---\nhello: world").length
+      end
+
+      def test_alias
+        assert_equal 5, calls("--- &yay\n- foo\n- *yay\n").length
+      end
+
+      private
+
+      def calls yaml
+        calls = []
+        Psych.parse_stream(yaml).each do |node|
+          calls << node
+        end
+        calls
+      end
+    end
+  end
+end
Index: test/psych/visitors/test_depth_first.rb
===================================================================
--- test/psych/visitors/test_depth_first.rb	(revision 0)
+++ test/psych/visitors/test_depth_first.rb	(revision 30624)
@@ -0,0 +1,49 @@
+require_relative '../helper'
+
+module Psych
+  module Visitors
+    class TestDepthFirst < TestCase
+      class Collector < Struct.new(:calls)
+        def initialize(calls = [])
+          super
+        end
+
+        def call obj
+          calls << obj
+        end
+      end
+
+      def test_scalar
+        collector = Collector.new
+        visitor   = Visitors::DepthFirst.new collector
+        visitor.accept Psych.parse_stream '--- hello'
+
+        assert_equal 3, collector.calls.length
+      end
+
+      def test_sequence
+        collector = Collector.new
+        visitor   = Visitors::DepthFirst.new collector
+        visitor.accept Psych.parse_stream "---\n- hello"
+
+        assert_equal 4, collector.calls.length
+      end
+
+      def test_mapping
+        collector = Collector.new
+        visitor   = Visitors::DepthFirst.new collector
+        visitor.accept Psych.parse_stream "---\nhello: world"
+
+        assert_equal 5, collector.calls.length
+      end
+
+      def test_alias
+        collector = Collector.new
+        visitor   = Visitors::DepthFirst.new collector
+        visitor.accept Psych.parse_stream "--- &yay\n- foo\n- *yay\n"
+
+        assert_equal 5, collector.calls.length
+      end
+    end
+  end
+end

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

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