1

Hi guys I have a question on adding methods to instance objects. There is something I don't get.

I'm trying to do a binary search tree in Ruby. So I made a node class like such:

class Node
    attr_accessor :value, :right, :left

    def initialize(value)
        @value = value  
    end
end

So when I want to create an instance object from that class I do this:

tree = Node.new(10)

But if I want to create a binary search tree I need left and right pointers for values that are less and higher than my root number.

So that should go something like this.

tree.left = Node.new(8)
tree.right = Node.new(13)

And if I want to go further I do this:

tree.left.left = Node.new(7)

And from my inspect method that I've adapted i get this:

"{10::{8::{6::nil|nil}|nil}|nil}" 

But from this:

left=Node.new(1).left = Node.new(2).left = Node.new(3)

I get:

{3::nil|nil} 

So, why doesn't this method chaining work like on the previous example?

Thanks

2 Answers 2

1

tap will help in your case:

left = Node.new(1).tap do |n|
  n.left = Node.new(2).tap do |n|
    n.left = Node.new(3)
  end
end

Nice article about how you can use the tap method.

Give it a shot, and let know if it worked!

Good luck!

Sign up to request clarification or add additional context in comments.

Comments

1

In ruby the value of assigning something to a variable is the value you are assigning. Which means that if you do

a = 5

The value of that expression is 5. Moreover, assignments are done right to left. Which means that in your code:

left=Node.new(1).left = Node.new(2).left = Node.new(3)

You first create Node.new(3) and then create Node.new(2) and assign the Node.new(3) to left of the 2 node. The result of this assignment is Node 3 which you assign to left of Node 1. Again the result of this assignment is Node 3 which you again assign to your variable left. So in the end it acts as if you just assigned Node 3 to left, but doing 2 unnecessary object instantiations on the way.

3 Comments

tnx for the answer, but how does this work then: tree.left.left = Node.new(7) //// "{10::{8::{6::nil|nil}|nil}|nil}"
In that case you first set tree = Node10, then tree.left = Node8. Then if you do tree.left.left = Node.new(7) is the same as if you did a = tree.left # => Node 8 a.left = Node.new(7) # Which means you set Node 7 to left of Node 8 This is different than left=Node.new(1).left = Node.new(2).left = Node.new(3)
tnx for you answer Piotr, so your saying that this would work left=Node.new(1).left = Node.new(2).left = Node.new(3) - If i did it on an instance object like tree = Node.new(10) like the following, tree.left=Node.new(1).left = Node.new(2).left = Node.new(3) - But how is it that I can append the same instance method .left with different new objects with different values in a row but I can't do it without an instance object like tree? Tnx Tom

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.