In Ruby What Does the "Receiver" Refer To

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



Leave a reply



Submit