Relationship between Ruby classes and modules

Source: Internet
Author: User

When getting started with Ruby, it is easy to get confused by the small trick of its classes and modules. Here we will write it out to help you understand it.

1. Everything in ruby is an object

Ruby is a Ground Object. All the components you see are objects. Numbers are objects, strings are objects, classes are objects, modules are objects, and even classes are objects ......

irb(main):001:0> 1.is_a? Object=> trueirb(main):002:0> Object.is_a? Object=> trueirb(main):003:0> Class.is_a? Object=> trueirb(main):007:0> class Testirb(main):008:1> end=> nilirb(main):009:0> Test.is_a? Object=> true

In fact, beginners like me who come from traditional object-oriented languages tend to ask questions: in Java, we can obviously see that the object is calling the method, but when I enter IRB, I didn't create any objects. How can I call methods such as puts? Here we will not discuss where the puts method comes from, but an object actually exists before the first line of Ruby code is executed. This object is called Main, which is the object.

irb(main):015:0> self=> mainirb(main):016:0> self.class=> Object

The environment is called top level context (top-level context ). It is the top of the Ruby call stack. Generally (when not Using TLC, the main object does not act as the current object) when you call methods such as puts, this main object acts as the caller (receiver ).
2. Ruby classes and modules

Ruby classes and modules can be regarded as the classification of objects. Each object in Ruby has a classification:

irb(main):017:0> Object.class=> Classirb(main):018:0> t=Test.new=> #<Test:0x1a5aa48>irb(main):019:0> t.class=> Testirb(main):020:0> Kernel.class=> Moduleirb(main):023:0> Module.class=> Classirb(main):024:0> Class.class=> Class

As you can see, the classification of objects is its common class. The classification of classes is class, the classification of kernel modules is module, the classification of class is also class, and the classification of module is also class.
Even in Ruby, we can think that there is only one classification, that is, the module, because the class is inherited from the module.

irb(main):011:0> Class.ancestors=> [Class, Module, Object, Kernel, BasicObject]

Except for a few differences, classes and modules can be treated equally. Classes are just enhancement modules. So what is the relationship between other common classes in Ruby and class/module? The answer is,Other classes (modules) are just class (module) instances..

irb(main):028:0> Test.instance_of? Class=> trueirb(main):013:0> Kernel.instance_of? Module=> true

Based on this principle, you can define a new class as follows:

irb(main):029:0> MyClass=Class.new doirb(main):030:1* def sayirb(main):031:2> puts "I am MyClass"irb(main):032:2> endirb(main):033:1> end=> MyClassirb(main):034:0> m=MyClass.new=> #<MyClass:0x1a4f798>irb(main):035:0> m.sayI am MyClass=> nil

A new class is created using the class. New operation, and this class is assigned to myclass. This new class is defined and can be used like other classes. In addition to proving that a common class is just a real class, this code also illustrates another problem: the class name is just a constant. We can check the current constant list for verification:

irb(main):038:0> Object.constants.grep /MyClass/=> [:MyClass]

3. Ruby Method Search

When a method is called in a ruby program, the Ruby interpreter starts from the receiver or self of the method and searches for the method along the ancestor chain of the object until the method is found or an exception is thrown.

Taking calling the puts method in the TLC as an example, in this case, the receiver of the puts method is implicitly acted by self, and the self is the object class Object main, then view the object class method:

irb(main):041:0> Object.methods.grep /puts/=> []

Obviously, the puts method does not exist in the object, so view the object's ancestor chain:

irb(main):042:0> Object.ancestors=> [Object, Kernel, BasicObject]

Following the ancestor chain, we can view the kernel method:

irb(main):043:0> Kernel.methods.grep /puts/=> [:puts]

Apparently, the puts method is located in the kernel. As we know before, the kernel is a module that is mixed into the (Mixin) class. Generally, when the module include is mixed, the module method becomes the instance method of the class, because the kernel module is mixed into the object class, you can call the puts method anywhere in Ruby code, because almost all Ruby classes inherit from the object.

PS. Private method:

The private method in ruby is sometimes annoying. But there is only one thing to remember: Private methods can only be called on the implicit receiver self, but the search rules for private method calls are the same as those for other methods. Therefore, even if the main object in the TLC has the puts method, it cannot be called as follows:

irb(main):046:0> self.putsNoMethodError: private method `puts' called for main:Object        from (irb):46        from C:/RailsInstaller/Ruby1.9.3/bin/irb:12:in `<main>'

In addition, do not confuse it with private in Java or other languages. Ruby's private method can be called in the subclass:

irb(main):052:0> class Dadirb(main):053:1> privateirb(main):054:1> def sayirb(main):055:2> puts "Dad says private"irb(main):056:2> endirb(main):057:1> end=> nilirb(main):058:0> class Son <Dadirb(main):059:1> def talkirb(main):060:2> sayirb(main):061:2> puts "son talk"irb(main):062:2> endirb(main):063:1> end=> nilirb(main):064:0> s=Son.new=> #<Son:0x1c90cb0>irb(main):065:0> s.talkDad says privateson talk

Finally, let's talk about the call of several common methods:

irb(main):067:0> Object.private_methods.grep /method/=> [:define_method, :method_missing,.........]

The method_missing and define_method of objcet are both private methods. Why is it correct to call method_missing inside the method, and an error is reported when define_method is called. define_method can be called only when the class context acts as self?

Object # method_missing is a private method of the object. It cannot be explicitly called by the recipient, but all objects can call this method implicitly.

The define_method is actually the Module # define_method method, which is the module's private instance method, and the class inherits the module class, so it becomes the class instance method, because all common classes are class instances, define_method becomes the class method of all common classes. Therefore, define_method can be used in the class context. At this time, self is acted by the class, instead, you cannot call this method when a specific object acts as self.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.