When you call a method, Ruby does two things.
1. Find this method. This method is called a method lookup.
2. Implement this method. To do this, Ruby needs something called self.
Such a process-discovering a method to execute-occurs in every object-oriented language. However, for a very dynamic language such as Ruby, it is particularly important to understand this process in depth. Have you ever wondered where a method is defined? If so, then it is absolutely essential to understand the method lookup and self in depth.
When a method is invoked, Ruby looks for that method in the object's class. Before giving more complicated examples, however, you need to understand two new concepts: the receiver (receiver) and the ancestor chain (ancetors chain).
The receiver is the object where you invoke the method. For example, in the My_string.reverse () statement, the my_string is the recipient.
To understand the concept of the ancestor chain, you can first observe any Ruby class. Imagine moving from one class to its superclass, then moving to the superclass, and so on until you reach the object class (the default superclass for all classes) and finally to the Basicobject class (the root node of the Ruby class architecture). In this process, the classpath you experience is the ancestor chain of the class (the ancestor chain can also contain modules).
Now that you know what the recipient and the ancestor chain are, you can summarize the process of method lookup in one sentence: To find a method, Ruby first looks in the recipient's class, and then finds it in the ancestor chain layers, until the method is found.
Class MyClass
def my_method
My_method () End-
class MySubClass <myclass
end
obj = Mysubclass.new
Obj.my_method () # => "My_method ()"
When the My_method () method is invoked, Ruby departs from receiver obj and comes to the MySubClass class. Because the My_method () method cannot be found here, Ruby goes up to the MyClass class, where the method is found.
If this method is not found here, then Ruby will go up the ancestor chain to the object class and the Basicobject class. In the order in which most people draw, this lookup behavior is referred to as the "one step to the right, then up" rule. That is, first step to the right to the recipient's class, and then up the ancestor chain up until the given method is found.
So far, we've focused on how to find a way, and now we're finally going to look at how to do it.
Imagine that you are the Ruby interpreter. If a person calls a method called My_method (), you find the method by "one step to the right, then up", and you find that this method is defined as follows:
def my_method
temp = @x +1
my_other_method (temp)
End
To implement this method, you need to answer two questions. First, which object does the instance variable @x belong to? Second, which object should you Invoke Method My_other_method ()?
As intelligent humans (not stupid computer programs), you are probably intuitively able to answer these two questions: the @x instance variable and the My_other_method () method belong to the receiver-the object that originally invoked the My_method () method. However, Ruby has no intuition, which is a luxury for it. When invoking a method, Ruby needs to hold a reference to the recipient, which is the existence of the reference that remembers which object is the receiver and uses it to execute the method. This recipient reference can also be used for you.