Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby modules - included do end block

Tags:

ruby

There is a module MyModule:

module MyModule    extend ActiveSupport::Concern    def first_method   end    def second_method   end    included do     second_class_method   end    module ClassMethods     def first_class_method     end      def second_class_method     end   end end 

When some class includes this module, it will have 2 methods exposed as instance methods (first_method and second_method) and 2 class methods (first_class_method and second_class_method) - it is clear.

It is said, that

included block will be executed within the context of the class that is including the module.

What does it mean exactly? Meaning, when exactly would this method (second_class_method) be executed?

like image 418
Andrey Deineko Avatar asked Jan 18 '15 12:01

Andrey Deineko


People also ask

What does Included do in Ruby?

Module#included allows modules to inject both class and instance methods, and execute associated code, from a single include. The documentation for ActiveSupport::Concern illustrates a typical use. It's injecting class methods into the calling class, and executing code. In this case, adding a scope.

Can modules include other modules Ruby?

Actually, Ruby facilitates the use of composition by using the mixin facility. Indeed, a module can be included in another module or class by using the include , prepend and extend keywords.

What is the difference between extend and include in Ruby?

In simple words, the difference between include and extend is that 'include' is for adding methods only to an instance of a class and 'extend' is for adding methods to the class but not to its instance.

What does Module do in Ruby?

In Ruby, modules are somewhat similar to classes: they are things that hold methods, just like classes do. However, modules can not be instantiated. I.e., it is not possible to create objects from a module. And modules, unlike classes, therefore do not have a method new .


2 Answers

Here's a practical example.

class MyClass   include MyModule end 

When you will include the module in a class, the included hook will be called. Therefore, second_class_method will be called within the scope of Class.

What happens here is

  1. first_method and second_method are included as instance-methods of MyClass.

    instance = MyClass.new instance.first_method # => whatever returned value of first_method is 
  2. The methods of ClassMethods are automatically mixed as class methods of MyClass. This is a common Ruby pattern, that ActiveSupport::Concern encapsulates. The non-Rails Ruby code is

    module MyModule   def self.included(base)     base.extend ClassMethods   end    module ClassMethods     def this_is_a_class_method     end   end end 

    Which results in

    MyClass.this_is_a_class_method 

    or in your case

    MyClass.first_class_method 
  3. included is a hook that is effectively to the following code

    # non-Rails version module MyModule   def self.included(base)     base.class_eval do       # somecode     end   end end  # Rails version with ActiveSupport::Concerns module MyModule   included do     # somecode   end end 

    It's mostly "syntactic sugar" for common patterns. What happens in practice, is that when you mix the module, that code is executed in the context of the mixer class.

like image 138
Simone Carletti Avatar answered Oct 08 '22 03:10

Simone Carletti


included is called when you include module into a class, it is used for defining relations, scopes, validations, ... It gets called before you even have created object from that class.

example

module M ...   included do     validates :attr, presence: true     has_many :groups   end  ... end 
like image 42
Nermin Avatar answered Oct 08 '22 02:10

Nermin