Ruby模块 – 包括do end block

有一个模块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 

当某个类include s这个模块时,它将有2个方法作为实例方法公开( first_methodfirst_method )和2个类方法( first_class_methodsecond_class_method ) – 很明显。

有人说,那

included块将在included模块的类的上下文中执行。

这究竟是什么意思? 意思是,何时执行此方法( second_class_method )?

这是一个实际的例子。

 class MyClass include MyModule end 

当您将模块包含在类中时,将调用included挂钩。 因此,将在Class的范围内调用second_class_method

这里发生的是

  1. first_methodfirst_method作为MyClass.实例方法包含在内MyClass.

     instance = MyClass.new instance.first_method # => whatever returned value of first_method is 
  2. ClassMethods的方法自动混合为MyClass类方法。 这是一个常见的Ruby模式,即ActiveSupport::Concern封装。 非Rails Ruby代码是

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

    结果如何

     MyClass.this_is_a_class_method 

    或者在你的情况下

     MyClass.first_class_method 
  3. included是一个有效地对以下代码的钩子

     # 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 

    对于常见模式,它主要是“语法糖”。 在实践中发生的是,当您混合模块时,该代码在混合器类的上下文中执行。

当您将module包含到类中时,将调用included ,它用于定义关系,范围,validation,……在您甚至从该类创建对象之前调用它。

 module M ... included do validates :attr, presence: true has_many :groups end ... end