Similarities and differences between module_function and extend self in Ruby, rubyextendself
When I read open-source Ruby code and write maintainability code, I often encounter the use of the two. What are the similarities and differences between the two?
Module_function
Ruby's module is a collection of methods and constants. The method in module can be divided into instance method and module method. When a module is included into a class, the method in module (Note: The method is not marked by module_function) it is the instance method in the class. The class in which the instance method is located must be instantiated before it can be called. The method marked by module_function (whether the method is public or private) that is, the module method and the instance method will also become private method. For the class where the include is located, it is private method, object. module_name error. All module methods can be called by module_name.method_name. public methods not marked by module_function cannot be called by module_name.method_name.
The module_function in module will change the method in module to the module method. For the class in which the module method is included, the module method is private method. Therefore, module_name.module_method can be called and cannot be called by the object. module_name is called.
The public method in module is the instance method for the class to be included, so object. public_method_in_module can be called. If you want a non-module method to be called by the module (module_name.not_module_method), you need to introduce extend self (extend self will be discussed below)
# Test. rbmodule MyModule def public_meth p "a public method, if the module is encoded to a class, can be called as object. public_meth "end def module_method p" a module method, can be called as module_name.module_method. but can not be call as object. module_method "end private def private_method_to_module_function p" a private_method, but can be call as module_name.module_method, because it was assigned to module_function "end def private_method p" I am a private method "end module_function: module_method,: Using MyModule. public_methrescue p "public method can not be called by module_name.public_meth" endbegin MyModule. private_methodrescue NoMethodError p "private method can not be called by module_name.module_method" endclass MyClass include MyModuleendobj = MyClass. newobj. public_methbegin obj. private_methodrescue NoMethodError p "private method in module can not be call by object. method_name "endbegin obj. module_methodrescue NoMethodError p "module method can not be called by object. method_name, for object, module method is private instance method "end # Call ruby test. rb "a module method, can be called as module_name.module_method. but can not be call as object. module_method "" a private_method, but can be call as module_name.module_method, because it was assigned to module_function "" public method can not be called by module_name.public_meth "" private method can not be called by module_name.module_method "" a public method, if the module is encoded to a class, can be called as object. public_meth "" private method in module can not be call by object. method_name "" module method can not be called by object. method_name, for object, module method is private instance method"
Summary:
• The method will be copied to class 'singleton class
• The instance method's visibility will become private
Extend self
Include is for adding methods to an instance of a class and extend is for adding class methods
The essence of extend is to add the class method to the class or module.
Extend self enables the instance method in the module to be called by module_name.instance_method, and retains the public or private attributes of the original method in the module, but does not change the labeled method to private like module_function.
#! /Usr/bin/env ruby # encoding: UTF-8 # test_extend.rbmodule MyModule extend self def public_meth p "a public_method extended by self can be called by module_name.public_meth and object. public_meth, included by a class "private_method end private def private_method p" a private method, can be call in module internal "endendclass MyClass include MyModuleendMyModule. public_methbegin MyModule. private_methodrescue NoMethodError p "private method in extend self module can not be called module_name.private_method" endobj = MyClass. newobj. public_methbegin obj. private_methodrescue NoMethodError p "private method can not be called by object. private_method "end # Call ruby test_extend.rb" a public_method extended by self can be called by module_name.public_meth and object. public_meth, included by a class "" a private method, can be call in module internal "" private method in extend self module can not be called module_name.private_method "" a public_method extended by self can be called by module_name.public_meth and object. public_meth, encoded ded by a class "" a private method, can be call in module internal "" private method can not be called by object. private_method"
Summary:
• No method copying involved
• No changes to method visibility
Summary
Module_function changes the public/private attribute of the original method in the module and changes the method to the module method, which can be called by module_name.module_method.
Extend self is self-inherited in the module. It does not change the public/private attribute of the method in the module and can be used by module_name.public_method.