Problem with recursive structure

Dear Rubists,

I have a little class called SimpleTree that makes a recursive
data structure of arrays. I am getting some funny behaviour when
I traverse the tree for printing.

The print routine is:

 def pp_branch(b)
     puts "(head) #{b[0]}"
     b.each { |item|
         next if item == b[0]        # avoid the head
         pp_branch(item) if item.type == Array
         puts "(leaf) #{item}"
     }
 end

Output looks like:

[“a”, “b”, [“z/”, “a”, “b”, [“y/”, “c”, “d”], “e”]]
(leaf) a
(leaf) b
(head) z/
(leaf) a
(leaf) b
(head) y/
(leaf) c
(leaf) d
(leaf) y/cd
(leaf) e

It is the line “y/cd” that gets me. Ruby (or is it me?) appears
to be flattening included array “y”.

Anyone help me with this?
TIA,

-mark

···

Mark Probert
GNPS - Optera Metro 3000
Tel (613) 768-1082 (ESN: 398-1082)
Mob (613) 715-2045
email: probertm@nortelnetworks.com

When you use string interpolation, to_s is called implicitly. So in the
above, “(leaf) #{item}” does “(leaf) #{item.to_s}” on Arrays. The to_s
of an Array flattens and concatenates the elements of an Array:

[ “y/”, “c”, “d” ].to_s
#=> “y/cd”

Try:

def pp_branch(b)
puts “(head) #{b[0]}”
b[1…-1].each { |item|
if Array === item
pp_branch(item)
else
puts “(leaf) #{item}”
end
}
end

_why

···

Mark Probert (probertm@nortelnetworks.com) wrote:

The print routine is:

def pp_branch(b)
    puts "(head) #{b[0]}"
    b.each { |item|
        next if item == b[0]        # avoid the head
        pp_branch(item) if item.type == Array
        puts "(leaf) #{item}"
    }
end

try this:

def pp_branch(b)
puts “(head) #{b[0]}”
b.each { |item|
next if item == b[0] # avoid the head
if item.type == Array
pp_branch(item)
else
puts “(leaf) #{item}”
end
}
end

looks like you are BOTH recursing on Array types AND printing them as leaves.

have you seen the RBTree from RAA? it’s fast.

-a

···

On Wed, 30 Oct 2002, Mark Probert wrote:

Dear Rubists,

I have a little class called SimpleTree that makes a recursive
data structure of arrays. I am getting some funny behaviour when
I traverse the tree for printing.

The print routine is:

 def pp_branch(b)
     puts "(head) #{b[0]}"
     b.each { |item|
         next if item == b[0]        # avoid the head
         pp_branch(item) if item.type == Array
         puts "(leaf) #{item}"
     }
 end

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

In article 5.1.0.14.2.20021029141528.00b146e8@zcard04k.ca.nortel.com,

Dear Rubists,

I have a little class called SimpleTree that makes a recursive
data structure of arrays. I am getting some funny behaviour when
I traverse the tree for printing.

The print routine is:

def pp_branch(b)
    puts "(head) #{b[0]}"
    b.each { |item|
        next if item == b[0]        # avoid the head
        pp_branch(item) if item.type == Array
        puts "(leaf) #{item}"
    }
end

Output looks like:

[“a”, “b”, [“z/”, “a”, “b”, [“y/”, “c”, “d”], “e”]]
(leaf) a
(leaf) b
(head) z/
(leaf) a
(leaf) b
(head) y/
(leaf) c
(leaf) d
(leaf) y/cd
(leaf) e

It is the line “y/cd” that gets me. Ruby (or is it me?) appears
to be flattening included array “y”.

Anyone help me with this?
TIA,

I don’t really have an answer for you, but I get something slightly
different(but still wrong) when I run this in 1.6.7:

(head) a
(leaf) b
(head) z/
(leaf) a
(leaf) b
(head) y/
(leaf) c
(leaf) d
(leaf) y/cd
(leaf) e
(leaf) z/aby/cde <------

note the last line is in addition to what you had.

I ran this in the debugger and it seems that at the end of a sub-array it
prints the while sub-array as a leaf. I couldn’t figure out why it was
doing this. What version of Ruby are you running?

Phil

···

Mark Probert probertm@nortelnetworks.com wrote:

When you use string interpolation, to_s is called implicitly.

Thanks. That is the "new thing today. :wink:

def pp_branch(b)
puts “(head) #{b[0]}”
b[1…-1].each { |item|
if Array === item
pp_branch(item)
else
puts “(leaf) #{item}”
end
}
end

That’s it. I was printing the branch as well as the leaf.
Doh!

Regards,
-mark.

_why

-mark

···

At 05:21 AM 10/30/2002 +0900, you wrote:


Mark Probert
GNPS - Optera Metro 3000
Tel (613) 768-1082 (ESN: 398-1082)
Mob (613) 715-2045
email: probertm@nortelnetworks.com

Hi, Ara.

try this:

Thank you. That got it.

have you seen the RBTree from RAA? it’s fast.

Yes, I did. For my purpose I want pure Ruby. I searched
and couldn’t find anything so I whipped one up. Given
that my tree is small (maybe 100 leaves or so), I don’t
have to search just print it once, it didn’t seem like
a big deal.

···

At 05:35 AM 10/30/2002 +0900, you wrote:

Hi, Phil.

···

At 05:35 AM 10/30/2002 +0900, you wrote:

I don’t really have an answer for you, but I get something slightly
different(but still wrong) when I run this in 1.6.7:

The problem is me printing the branch array as well as the leaf.
Basically, I missed the else branch …

-mark.