Exforsys
+ Reply to Thread
Results 1 to 3 of 3

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-leaf structure which ...

  1. #1
    Anthony Webster Guest

    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





  2. #2
    Simon Strandgaard Guest

    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



  3. #3
    Simon Strandgaard Guest

    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)



    •    Sponsored Ads



Latest Article

Network Security Risk Assessment and Measurement

Read More...