diff --git a/lib/sof/all.rb b/lib/sof/all.rb index 841fa004..97f9986e 100644 --- a/lib/sof/all.rb +++ b/lib/sof/all.rb @@ -1,11 +1,11 @@ require_relative "util" +require_relative "node" require_relative "members" require_relative "volotile" require_relative "writer" require_relative "array" require_relative "hash" require_relative "occurence" -require_relative "node" Symbol.class_eval do def to_sof() diff --git a/lib/sof/array.rb b/lib/sof/array.rb index a91878cc..64193614 100644 --- a/lib/sof/array.rb +++ b/lib/sof/array.rb @@ -1,15 +1,7 @@ -Array.class_eval do - def to_sof_node(writer , level) - node = Sof::ArrayNode.new() - each do |object| - node.add writer.to_sof_node( object , level + 1) - end - node - end -end module Sof class ArrayNode < Node - def initialize + def initialize ref + super(ref) @children = [] end attr_reader :children @@ -17,6 +9,7 @@ module Sof @children << c end def out io , level = 0 + super long_out(io , level) end @@ -30,4 +23,13 @@ module Sof end end end -end \ No newline at end of file +end +Array.class_eval do + def to_sof_node(writer , level , ref ) + node = Sof::ArrayNode.new(ref) + each do |object| + node.add writer.to_sof_node( object , level + 1) + end + node + end +end diff --git a/lib/sof/hash.rb b/lib/sof/hash.rb index 963b2f0c..93b2c58e 100644 --- a/lib/sof/hash.rb +++ b/lib/sof/hash.rb @@ -1,6 +1,7 @@ module Sof class HashNode < Node - def initialize + def initialize ref + super(ref) @children = [] end attr_reader :children @@ -8,6 +9,7 @@ module Sof @children << [key,val] end def out io , level = 0 + super indent = " " * level @children.each_with_index do |child , i| key , val = child @@ -22,8 +24,8 @@ module Sof end Hash.class_eval do - def to_sof_node(writer , level) - node = Sof::HashNode.new() + def to_sof_node(writer , level , ref) + node = Sof::HashNode.new(ref) each do |key , object| k = writer.to_sof_node( key ,level + 1) v = writer.to_sof_node( object ,level +1) diff --git a/lib/sof/members.rb b/lib/sof/members.rb index 33d0ff15..188f324d 100644 --- a/lib/sof/members.rb +++ b/lib/sof/members.rb @@ -7,15 +7,17 @@ module Sof @root = root @counter = 1 @objects = {} + @referenced = false add(root , 0) end - attr_reader :objects , :root + attr_reader :objects , :root , :referenced def add object , level return if is_value?(object) if( occurence = @objects[object] ) #puts "reset level #{level} at #{occurence.level}" occurence.level = level if occurence.level > level + occurence.referenced = true return end o = Occurence.new( object , @counter , level ) diff --git a/lib/sof/node.rb b/lib/sof/node.rb index d7c8307c..88c42409 100644 --- a/lib/sof/node.rb +++ b/lib/sof/node.rb @@ -2,16 +2,22 @@ module Sof #abstract base class for nodes in the tree + # may be referenced (should be a simple name or number) class Node + def initialize referenced + @referenced = referenced + end include Util # must be able to output to a stream def out io ,level - raise "abstract #{self}" + io.write "&#{referenced} " if referenced end + attr_reader :referenced end class SimpleNode < Node def initialize data + super(nil) @data = data end attr_reader :data @@ -21,7 +27,8 @@ module Sof end class ObjectNode < Node - def initialize data + def initialize data , ref + super(ref) @data = data @children = [] end @@ -30,6 +37,7 @@ module Sof @children << [k,v] end def out io , level = 0 + super io.write(@data) indent = " " * (level + 1) @children.each_with_index do |child , i| diff --git a/lib/sof/occurence.rb b/lib/sof/occurence.rb index 2493ce94..8fc99481 100644 --- a/lib/sof/occurence.rb +++ b/lib/sof/occurence.rb @@ -7,7 +7,7 @@ module Sof @level = level end attr_reader :object , :number - attr_accessor :level + attr_accessor :level , :referenced end end diff --git a/lib/sof/writer.rb b/lib/sof/writer.rb index 3220749a..047d8a51 100644 --- a/lib/sof/writer.rb +++ b/lib/sof/writer.rb @@ -22,19 +22,20 @@ module Sof #puts "level #{level} at #{occurence.level}" return SimpleNode.new("*#{occurence.number}") end + ref = occurence.referenced ? occurence.number : nil if(object.respond_to? :to_sof_node) #mainly meant for arrays and hashes - object.to_sof_node(self , level ) + object.to_sof_node(self , level , ref ) else - object_sof_node(object , level ) + object_sof_node(object , level , ref ) end end - def object_sof_node( object , level) + def object_sof_node( object , level , ref) head = object.class.name + "(" atts = attributes_for(object) immediate , extended = atts.partition {|a| is_value?(get_value(object , a) ) } head += immediate.collect {|a| "#{a}: #{get_value(object , a).to_sof()}"}.join(", ") + ")" - node = ObjectNode.new(head) + node = ObjectNode.new(head , ref) extended.each do |a| val = get_value(object , a) node.add( to_sof_node(a,level + 1) , to_sof_node(val, level + 1) ) diff --git a/test/sof.rb b/test/sof.rb index 2636d7b2..d86b296b 100644 --- a/test/sof.rb +++ b/test/sof.rb @@ -78,12 +78,12 @@ class BasicSof < MiniTest::Test ar = [true, 1 ] ar << ar @out = Sof::Writer.write(ar) - check "-true\n-1\n-*1" + check "&1 -true\n-1\n-*1" end def test_object_recursive object = ObjectWithAttributes.new object.extra = object @out = Sof::Writer.write(object) - check "#{OBJECT_STRING}\n :extra *1" + check "&1 #{OBJECT_STRING}\n :extra *1" end end \ No newline at end of file