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 "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()

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
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
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
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)

View File

@ -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 )

View File

@ -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|

View File

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

View File

@ -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) )

View File

@ -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