Home > Enterprise >  When do I need to use self.instance_method vs instance_method alone?
When do I need to use self.instance_method vs instance_method alone?

Time:04-20

I'm hoping someone can explain why I get the same behavior from both of these methods and what that means for when to or not to use self.

def my_instance_method(arg)
  'execute some code' if another_instance_method_of_same_class?(arg)
end

seems to behave exactly the same as

def my_instance_method(arg)
  'execute some code' if self.another_instance_method_of_same_class?(arg)
end

My apologies if my search skills aren't up to par but I couldn't find the exact answer to this question, just explanations of what self does (which made me think I should need it). I'm using the latest version of Ruby. Thank you.

CodePudding user response:

There are a few differences between self.foo(...) and foo(...), but they're mostly equivalent.

Privacy

private methods can only be called via foo directly, and never with an explicit receiver. So if foo is marked private, then you have to call it without self.

class Example

  private def foo(x)
    x   1
  end

  def bar
    foo # Works fine
    self.foo # Error: foo is private
  end

end

Shadowing

If you have a local variable called foo in the current function, then writing foo without arguments will reference the local variable instead

class Example

  def foo(*args)
    puts "Hello :)"
  end

  def bar
    foo = 100 # Just an ordinary variable; no relation to the above method
    foo # This refers to the local variable called "foo"
    self.foo # This calls the method foo() with no arguments
    foo(1) # This calls the method foo() with one argument
    self.foo(1) # Equivalent to the above; calls with one argument
  end

  def baz
    foo # There's no local variable called "foo", so this calls the method
  end

end

Assignment

If the method you're talking about is an assignment method (i.e. ends in =), then it must always be called with an explicit receiver

class Example

  def foo=(value)
    puts "Assigning foo = #{value}"
  end

  def bar
    foo = 0 # This creates a new local variable called foo and assigns to it
    self.foo = 0 # Calls foo= on self
  end

end
  • Related