Exforsys

Online Training

Traversing Composites with Visitors

This is a discussion on Traversing Composites with Visitors within the Software Patterns forums, part of the Testing category; Hi, I'm trying to make head or tail of this and failing miserably! I have a simple component/composite-...


Go Back   Exforsys > Testing > Software Patterns

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 10-11-2003, 09:07 AM
Anthony Webster
Guest
 
Posts: n/a
Traversing Composites with Visitors

Hi,

I'm trying to make head or tail of this and failing miserably! I have a
simple component/composite-leaf structure which just store names. I'd like
to print it like a directory in the format below but I can't figure it out.
People keep talking about recursion with depth values but the visit calls
aren't recursive so I haven't a clue.

So far with simple printfs I get the following:

A
B
C
D
E

but I'd like

A
+-B
| +-C
| +-D
+-E

HELP!

Many Thanks

Tony


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 10-11-2003, 11:23 AM
Simon Strandgaard
Guest
 
Posts: n/a
Re: Traversing Composites with Visitors

On Sat, 11 Oct 2003 15:07:47 +0200, Anthony Webster wrote:
> but I'd like
>
> A
> +-B
> | +-C
> | +-D
> +-E
>
> HELP!



Something like this (Ruby-example in the bottom of this mail)

server> ruby vis.rb
+-A
+-B
| +-C
| +-E
| | +-D
| | +-F
| | +-G
| +-H
+-I
server>


The trick is to determine whether or not you are dealing with
the last child, if not then you use '|' otherwise use space.

--
Simon Strandgaard




class Leaf
def initialize(name)
@name = name
end
attr_reader :name
def accept(visitor)
visitor.visit_leaf self
end
end

class Composite
def initialize(name, *children)
@name = name
@children = children
end
attr_reader :children, :name
def accept(visitor)
visitor.visit_composite self
end
end

class Visitor
def initialize
@result = []
@last = true
end
attr_reader :result
def visit_leaf(i)
@result << "+-" + i.name
end
def visit_composite(i)
pad = @last ? " " : "|"
i.children[0..-2].each {|child|
@last = false
child.accept self
}
@last = true
i.children.last.accept self
@result.map!{|s| pad + " " + s }
@result.unshift "+-" + i.name
end
end

data = Composite.new('A',
Composite.new('B',
Composite.new('C',
Leaf.new('D'),
Composite.new('E',
Leaf.new('F'),
Leaf.new('G')
),
Leaf.new('H')
)
),
Leaf.new('I')
)

v = Visitor.new
data.accept v
puts v.result
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 10-11-2003, 11:44 AM
Simon Strandgaard
Guest
 
Posts: n/a
Re: Traversing Composites with Visitors

On Sat, 11 Oct 2003 17:23:16 +0200, Simon Strandgaard wrote:

> On Sat, 11 Oct 2003 15:07:47 +0200, Anthony Webster wrote:
>> but I'd like
>>
>> A
>> +-B
>> | +-C
>> | +-D
>> +-E
>>
>> HELP!

>
>
> Something like this (Ruby-example in the bottom of this mail)
>
> server> ruby vis.rb
> +-A
> +-B
> | +-C
> | +-E
> | | +-D
> | | +-F
> | | +-G
> | +-H
> +-I
> server>


Argh.. too quick.. now its outputs correct ;-)

server> ruby vis.rb
+-A
+-B
| +-C
| +-D
| +-E
| | +-F
| | +-G
| +-H
+-I
server>


class Leaf
def initialize(name)
@name = name
end
attr_reader :name
def accept(visitor)
visitor.visit_leaf self
end
end

class Composite
def initialize(name, *children)
@name = name
@children = children
end
attr_reader :children, :name
def accept(visitor)
visitor.visit_composite self
end
end

class Visitor
def initialize
@last = true
end
def visit_leaf(i)
["+-" + i.name]
end
def visit_composite(i)
pad = @last ? " " : "|"
res = []
i.children[0..-2].each{|child|
@last = false
res += child.accept(self)
}
@last = true
res += i.children.last.accept(self)
res.map!{|s| pad + " " + s }
res.unshift "+-" + i.name
res
end
end

data = Composite.new('A',
Composite.new('B',
Composite.new('C',
Leaf.new('D'),
Composite.new('E',
Leaf.new('F'),
Leaf.new('G')
),
Leaf.new('H')
)
),
Leaf.new('I')
)

puts data.accept(Visitor.new)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -4. The time now is 05:34 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.1.0
Copyright 2004 - 2007 Exforsys Inc. All rights reserved.