adding the actual references for referenced objects

This commit is contained in:
Torsten Ruger 2014-08-18 13:53:05 +03:00
parent 67c3fb6cb0
commit 1dee9a4bd1
8 changed files with 40 additions and 25 deletions

View File

@ -1,11 +1,11 @@
require_relative "util" require_relative "util"
require_relative "node"
require_relative "members" require_relative "members"
require_relative "volotile" require_relative "volotile"
require_relative "writer" require_relative "writer"
require_relative "array" require_relative "array"
require_relative "hash" require_relative "hash"
require_relative "occurence" require_relative "occurence"
require_relative "node"
Symbol.class_eval do Symbol.class_eval do
def to_sof() def to_sof()

View File

@ -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 module Sof
class ArrayNode < Node class ArrayNode < Node
def initialize def initialize ref
super(ref)
@children = [] @children = []
end end
attr_reader :children attr_reader :children
@ -17,6 +9,7 @@ module Sof
@children << c @children << c
end end
def out io , level = 0 def out io , level = 0
super
long_out(io , level) long_out(io , level)
end end
@ -31,3 +24,12 @@ module Sof
end end
end end
end 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

View File

@ -1,6 +1,7 @@
module Sof module Sof
class HashNode < Node class HashNode < Node
def initialize def initialize ref
super(ref)
@children = [] @children = []
end end
attr_reader :children attr_reader :children
@ -8,6 +9,7 @@ module Sof
@children << [key,val] @children << [key,val]
end end
def out io , level = 0 def out io , level = 0
super
indent = " " * level indent = " " * level
@children.each_with_index do |child , i| @children.each_with_index do |child , i|
key , val = child key , val = child
@ -22,8 +24,8 @@ module Sof
end end
Hash.class_eval do Hash.class_eval do
def to_sof_node(writer , level) def to_sof_node(writer , level , ref)
node = Sof::HashNode.new() node = Sof::HashNode.new(ref)
each do |key , object| each do |key , object|
k = writer.to_sof_node( key ,level + 1) k = writer.to_sof_node( key ,level + 1)
v = writer.to_sof_node( object ,level +1) v = writer.to_sof_node( object ,level +1)

View File

@ -7,15 +7,17 @@ module Sof
@root = root @root = root
@counter = 1 @counter = 1
@objects = {} @objects = {}
@referenced = false
add(root , 0) add(root , 0)
end end
attr_reader :objects , :root attr_reader :objects , :root , :referenced
def add object , level def add object , level
return if is_value?(object) return if is_value?(object)
if( occurence = @objects[object] ) if( occurence = @objects[object] )
#puts "reset level #{level} at #{occurence.level}" #puts "reset level #{level} at #{occurence.level}"
occurence.level = level if occurence.level > level occurence.level = level if occurence.level > level
occurence.referenced = true
return return
end end
o = Occurence.new( object , @counter , level ) o = Occurence.new( object , @counter , level )

View File

@ -2,16 +2,22 @@
module Sof module Sof
#abstract base class for nodes in the tree #abstract base class for nodes in the tree
# may be referenced (should be a simple name or number)
class Node class Node
def initialize referenced
@referenced = referenced
end
include Util include Util
# must be able to output to a stream # must be able to output to a stream
def out io ,level def out io ,level
raise "abstract #{self}" io.write "&#{referenced} " if referenced
end end
attr_reader :referenced
end end
class SimpleNode < Node class SimpleNode < Node
def initialize data def initialize data
super(nil)
@data = data @data = data
end end
attr_reader :data attr_reader :data
@ -21,7 +27,8 @@ module Sof
end end
class ObjectNode < Node class ObjectNode < Node
def initialize data def initialize data , ref
super(ref)
@data = data @data = data
@children = [] @children = []
end end
@ -30,6 +37,7 @@ module Sof
@children << [k,v] @children << [k,v]
end end
def out io , level = 0 def out io , level = 0
super
io.write(@data) io.write(@data)
indent = " " * (level + 1) indent = " " * (level + 1)
@children.each_with_index do |child , i| @children.each_with_index do |child , i|

View File

@ -7,7 +7,7 @@ module Sof
@level = level @level = level
end end
attr_reader :object , :number attr_reader :object , :number
attr_accessor :level attr_accessor :level , :referenced
end end
end end

View File

@ -22,19 +22,20 @@ module Sof
#puts "level #{level} at #{occurence.level}" #puts "level #{level} at #{occurence.level}"
return SimpleNode.new("*#{occurence.number}") return SimpleNode.new("*#{occurence.number}")
end end
ref = occurence.referenced ? occurence.number : nil
if(object.respond_to? :to_sof_node) #mainly meant for arrays and hashes 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 else
object_sof_node(object , level ) object_sof_node(object , level , ref )
end end
end end
def object_sof_node( object , level) def object_sof_node( object , level , ref)
head = object.class.name + "(" head = object.class.name + "("
atts = attributes_for(object) atts = attributes_for(object)
immediate , extended = atts.partition {|a| is_value?(get_value(object , a) ) } immediate , extended = atts.partition {|a| is_value?(get_value(object , a) ) }
head += immediate.collect {|a| "#{a}: #{get_value(object , a).to_sof()}"}.join(", ") + ")" 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| extended.each do |a|
val = get_value(object , a) val = get_value(object , a)
node.add( to_sof_node(a,level + 1) , to_sof_node(val, level + 1) ) node.add( to_sof_node(a,level + 1) , to_sof_node(val, level + 1) )

View File

@ -78,12 +78,12 @@ class BasicSof < MiniTest::Test
ar = [true, 1 ] ar = [true, 1 ]
ar << ar ar << ar
@out = Sof::Writer.write(ar) @out = Sof::Writer.write(ar)
check "-true\n-1\n-*1" check "&1 -true\n-1\n-*1"
end end
def test_object_recursive def test_object_recursive
object = ObjectWithAttributes.new object = ObjectWithAttributes.new
object.extra = object object.extra = object
@out = Sof::Writer.write(object) @out = Sof::Writer.write(object)
check "#{OBJECT_STRING}\n :extra *1" check "&1 #{OBJECT_STRING}\n :extra *1"
end end
end end