I will answer your question, but that will not help you understand when you are to use the prefix self. when defining methods. I therefore need to first present some background information on instance methods.
Suppose we have the following class definition.
class C
puts "self = #{self}
def i
puts "self in i = #{self}"
"i"
end
def self.c
puts "self in c = #{self}"
"c"
end
singleton_class.define_method(:s) do
puts "self in s = #{self}"
"s"
end
end
#=> :s
self = C
I have defined an instance method C#i, a class method C::c and an instance method on C singleton class, s.
Note that, since self #=> C within the class, writing def self.c ... is precisely the same as def C.c .... The only reasons for writing self is that if we rename the class we don't have to change def self.c ... and
"self" is harder to misspell than, say, "PhilharmonicOrchestras".
Unsurprisingly,
C.instance_methods(false)
#=> [:i]
instance = C.new
#=> #<C:0x00007ff0011074f0>
instance.i
#=> "i"
self in i = #<C:0x00007ff0011074f0>
Now consider the last two methods:
C.methods(false)
#=> [:s, :c]
C.c
#=> "c"
self in c = C
C.singleton_class.instance_methods(false)
#=> [:s, :c]
C.s
#=> "s"
self in s = C
This shows that defining a method def self.class.c is merely a shorthand way of telling Ruby that you wish to create an instance method s on C's singleton class. Similarly, references to "class methods" are shorthand for those same instance methods. In fact, there is no need to define methods with the prefix self.. You could instead use singleton_class and define_method, as I have done, or elect one of several other ways, the most common being
class C
class << self
def s
puts "self in s = #{self}"
"s"
end
end
end
where class << self .. end causes self to change from C to C.singleton_class.
You defined a method which I will modify a bit:
self
#=> main
def my_instance_method
puts "self = #{self}, self.class = #{self.class}"
'execute some code'
end
my_instance_method
#=> "execute some code"
self = main, self.class = Object
As all methods are instance methods this must be one as well, namely a private instance method of Object:
Object.private_instance_methods.include?(:my_instance_method)
#=> true
Being a private instance method we cannot invoke it on an explicit receiver that is an instance of Object (main), but we can write:
Object.new.send(:my_instance_method)
#=> "execute some code"
self = #<Object:0x00007f988514e180>, self.class = Object
Note that if it were made a public method it would be available for use by all objects, which obviously would lead to disaster.
Next consider:
def self.your_instance_method
puts "self = #{self}, self.class = #{self.class}"
'execute some code'
end
your_instance_method
#=> "execute some code"
self = main, self.class = Object
This method must be defined on self's (main's) singleton class, which we may confirm:
self.singleton_class.instance_methods.include?(:your_instance_method)
#=> true
Therefore, the implicit receiver of
your_instance_method
is self, which equals main, giving the same result as
self.send(:your_instance_method)
This is a complicated subject (concerning Ruby's Object Model), particularly for someone fairly new to Ruby, so don't be concerned if you are not able to follow all of what I have said.