Ezerk Ezerk - 3 months ago 10
Ruby Question

Ruby BST: why does this code need 'self' to make a new node?

I wrote the binary search tree code with Ruby. I'm now wondering why this code needs

self
in
self.left = Node.new(3)
to make a new node.

I was thinking that self can be removed like this
left = Node.new(3)
because in this case receiver is obvious(an instance to which insert_left method applied). But it seems wrong.. Can you please help me why my thought is wrong.

module BinaryTree
class Node
attr_accessor :value, :left, :right

def initialize(value)
@value = value
end

def insert(v)
case @value <=> v
when 1 then insert_left(v)
when -1 then insert_right(v)
when 0 then nil
end
end


private
def insert_left(v)
if left
left.insert(v)
else
self.left = Node.new(v)
end
end

def insert_right(v)
if right
right.insert(v)
else
self.right = Node.new(v)
end
end

end
end

Answer

When calling left = x that's interpreted as a variable assignment. Calling self.left = x is a method call of left= on self. These are obviously two different things but unless you're familiar with the notation this might not make any sense. It isn't especially intuitive and is rather perplexing for beginners, especially when x = left works fine without having to be explicit about left being a variable or a method call.

Unlike some languages that have prefixes on local variables (Perl, PHP, etc.) there's no such identifier in Ruby. As such it interprets things of the form lvalue = expr to be variable assignments and object.property = expo to be method calls to a mutator method.

Ruby does identify instance and class level variables like @x = expr and @@y = expr but that's a different thing altogether.