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