In Ruby what does the receiver refer to?
In Ruby (and other languages that take inspiration from SmallTalk) objects are thought of as sending and receiving 'messages'.
In Ruby, Object, the base class of everything, has a send method: Object.send For example:
class Klass
def hello
"Hello!"
end
end
k = Klass.new
k.send :hello #=> "Hello!"
k.hello #=> "Hello!"
In both of these cases k is the receiver of the 'hello' message.
How to understand sender and receiver in Ruby?
A core concept in Object Orientation is messaging and early conceptualization borrowed much from the Actor Model of computation. Alan Kay, the guy who coined the term Object Oriented and invented one of the first OO languages SmallTalk, has voiced regret at using a term which put the focus on objects instead of on messages, which he considered the stronger idea.
When talking about a message, there's a natural "sender" and "receiver" of the message. The sender is the object which invokes a method, the receiver is the object whose method is invoked. In Ruby, if one calls a method without explicitly naming an object, that sends the method name and its args as a message to the default receiver self
.
In OO, "making a call", "invoking a method", and "sending a message" are equivalent concepts. Similarly "being called", "having one's method invoked", and "receiving a message" are equivalent.
Way to refer to the receiver of 'Array#each'
You should be able to just reference it:
my_thing.each {|one_thing| puts my_thing }
Is the caller in Java the same as the receiver in Ruby?
In your example x
is not calling hello()
. Whatever object contains that snippet is "calling" (i.e., it's the "caller"). In Java, x
can be referred to as the receiver; it is receiving the call to the hello()
method.
Implicit receiver
In the text you quote the "not yourself" means not in the same context (object) that the call was made.
In this example of a private method...
class Foo
def bar
baz
end
private
def baz
'hello'
end
end
If you do
Foo.new.baz
You get an error, because baz
was called with an explicit receiver (the part before the dot... Foo.new
)
If you do
Foo.new.bar
=> "hello"
And that works because method bar
called baz
without a receiver. It was able to call it without a receiver because bar
(like baz
) are both instance methods of the Foo
object, so they have the same context (the same self
). the bar
method was calling baz
on the same object that contains the bar
method (i.e. "itself" or "yourself" if you think of yourself as sitting in the object as you write the object's methods).
Now rewrite the class as...
class Foo
def bar
self.baz
end
private
def baz
'hello'
end
end
And now you see that bar
no longer works, since you privded the receiver self
(an explicit receiver) on the call to baz
within the method bar
. Technically the exact same functionality (no receiver is the same as self as receiver) , but Ruby implements private methods by disallowing explicit receivers, even self
. So, as stated, private methods can't be called with an explicit receiver.
Every time you call a method on an object you are not calling that method on yourself (i.e. your context).
'george'.upcase
=> "GEORGE"
For upcase
the explicit receiver is the part before the dot (the string object "george")
If you did
upcase
without specifying a receiver, it assumes you want to run upcase
in your context (self
) which in IRB is main:Object. That's why you get
NameError: undefined lcoal variable or method `upcase' for main:Object
k.send :hello - if k is the receiver , who is the sender?
Whatever object contains this code is sending the message — presumably main. Let's look at it with more explicit objects and normal message-passing.
class Person
attr_accessor :first_name, :last_name
def initialize(first_name, last_name)
@first_name, @last_name = first_name, last_name
end
def marry(other)
self.last_name = other.last_name
end
end
bob = Person.new('Bob', 'Smith')
patty = Person.new('Patricia', 'Johnson')
patty.marry bob
In the last line of this code, main is sending marry
to patty, and patty in turn sends herself last_name=
and sends bob last_name
.
How to return the receiver from a method in Ruby?
self
refers to the object itself:
class Fixnum
def foo
self
end
end
Related Topics
What Is the Best Diff Library in Ruby
Unable to Load Gem Cocoa Pods While Creating Repo
Understanding Ruby Symbol as Method Call
How to Load Some Activerecord Models from a Yaml File and Save Them to the Db
Heroku App Fails to Start - 'Require': No Such File to Load -- Sinatratestapp (Loaderror)
Rails 3: Call Functions Inside Controllers
Paperclip Amazon S3 Setup with Heroku
What Does the Underscore Mean in Literal Numbers
If Else Statements in .Html.Erb in Views
Rails/Rspec: How to Test #Initialize Method
<Rubygems> How to Change Gem Environment Settings
Rails Before_Filter for Specific Actions in Controller
How to Route Controllers Without Crud Actions
Determine If One Array Contains All Elements of Another Array