I was reading a Ruby book and came across this definition of the pseudo-variable self:
self - receiver object of the current method
self
is a special variable that changes depending on the context. To be more specific, it is receiver object of the current method, as you mentioned. To understand this, we need to understand what receiver means.
See Programming Ruby: More About Methods and Classes and Objects.
You call a method by specifying a receiver, the name of the method, and optionally some parameters and an associated block.
connection.downloadMP3("jitterbug") { |p| showProgress(p) }
In this example, the object
connection
is the receiver,downloadMP3
is the name of the method,"jitterbug"
is the parameter, and the stuff between the braces is the associated block.
foo = "hello"
bar = foo.dup
class <<foo
def to_s
"The value is '#{self}'"
end
def twoTimes
self + self
end
end
foo.to_s » "The value is 'hello'"
foo.twoTimes » "hellohello"
bar.to_s » "hello"
In foo.twoTimes
, foo
part is called the receiver of the method call.
So, within the twoTimes
method, self
refers to the object foo
in the context.
There is also a very good explanation here
self - receiver object of the current method
"Method calling" in Ruby is accomplished through a message-sending mechanism. So
some_object.some_method(args)
is a shorthand for
some_object.send(:some_method, args)
I think this is what the quote is referring to: "self" is the object to which the message (or method) has been sent: the receiver of the current method.
The whole message-sending thing is part of what makes Ruby so dynamic. It makes it easy for an object to define method_missing
for messages it doesn't currently handle and decide what to do with them. Rails uses this a lot: ActiveRecord, for example has the "find_by..." syntax, which figures out what's wanted from the name of the method called/sent.
Ruby and other languages (such as Smalltalk and Objective-C) prefer the term "message passing", whereas Java and C++ prefer "method invocation". That is, the "Java way" is to call a method on an object — running code in the context of an object — whereas the "Ruby way" is to send an object a message, to which the object responds by running its method.
Ruby would describe the line my_string.length
as "sending my_string
the length
message". The my_string
receives the message, and so is called the receiver; inside the definition of the length
method, self
would refer to my_string
. You can get the same effect with my_string.send(:length)
.
Thinking of this concept in terms of message passing is more flexible than thinking in terms of method invocation. To invoke a method on an object, that method must have been pre-defined, whereas you can send an object a message that it can choose to handle dynamically (with respond_to?
and method_missing
). This flexibility is one aspect that allows Ruby to be used as concise domain-specific languages (DSL).