0

I'm writing a recursive toString method in a binary tree class in Ruby. The algorithm uses two methods as shown below. I have a local variable called result, which is to hold the concatenation of all the values in the tree. For some odd reason, when I concatenate result in the toString algorithm, the root of the tree changes.

def toString
  currentNode = @root
  result = "<"

  if nil != currentNode
    result << (getString currentNode, result)
  end

  result = result + ">"
  return result
end

def getString(currentNode, result)
  if currentNode != nil
    result = currentNode.value.toString

    if nil != currentNode.left
      result << "," # Through debugging, I have noticed that it starts here!!!! 
      result.concat (self.getString currentNode.left, result)
    end

    if nil != currentNode.right
      result << ","
      result.concat (self.getString currentNode.right, result)
    end
  end
  return result
end

So, where I have noted in the comment above, the value at the root of the tree begins to change. Instead of concatenating with result, it concatenates with the root, which changes the tree, instead of simply traversing and concatenating the values. I have used << and concat. Same result. Could someone please help shed some light on this? I am fairly new to Ruby. Thank you. :)

6
  • 1
    Please add an example of your input and current output and what you expect the output to be. It's difficult to tell from your description what toString is supposed to yield. Commented Jul 24, 2014 at 11:37
  • What is currentNode.value.toString? Commented Jul 24, 2014 at 11:38
  • 2
    FYI to_s would be a more idiomatic name than toString in Ruby. Commented Jul 24, 2014 at 11:39
  • The tree has nodes and the value of a node could be one of a series of classes, including the tree class itself. i.e. tree inside of a tree. Each of those classes has a to_string Commented Jul 24, 2014 at 11:44
  • Actual output <<Dog,700,Cat,700,Cat>> Desired output <<Dog, 700, Cat>> Commented Jul 24, 2014 at 11:46

1 Answer 1

1

Contrary to other languages (like or ) Strings in ruby are not immutable (by default). This means that if currentNode.value.toString returns the actual string value of the value (and not a copy of it) calling << on it will change the value itself:

class Dummy
  attr_accessor :value
end

dummy = Dummy.new
dummy.value = 'test'

result = dummy.value
result << 'something else'
# => "testsomething else"
dummy.value
# => "testsomething else" # !!!!

To avoid that you need to make sure you return a duplicate of the value, and not the value itself.

dummy.value = 'test'

result = dummy.value.dup
result << 'something else'
# => "testsomething else"
dummy.value
# => "test" # :-)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.