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/