嵌套模块和方法挂钩

时间:2013-01-30 10:34:07

标签: ruby-on-rails ruby

我是ruby(java背景)的新手,所以如果这是一个非常愚蠢的问题,我很抱歉。

我正在学习一些关于模块的教程,它们看起来有点类似于静态类。我无法绕过头来解决这个问题,为什么你会这样做:

module ExampleModule

  def self.included(base)
      base.extend(ClassMethods)
  end

  module ClassMethods
      def myMethod
      end
  end
end

为什么不将ClassMethods中的方法放入ExampleModule并保存添加方法挂钩。我确定我错过了一些非常基本的东西,但我已经在这一段时间了,所以我觉得有必要问一下。

2 个答案:

答案 0 :(得分:3)

这是一个红宝石成语。当您需要以下模块时,它非常有用:

  • 将一些实例方法添加到类
  • 同时添加类方法/像Java静态方法/

同时

示例:

module ExampleModule
  def self.included(base)
    puts 'included'
    base.extend(ClassMethods)
  end

  def foo
    puts 'foo!'
  end

  module ClassMethods
    def bar
      puts 'bar!'
    end
  end
end

class ExampleClass
  include ExampleModule
end

ExampleClass.bar

ExampleClass.new.foo

如果您只想添加课程方法,则不需要这种习惯用法,只需在模块中添加方法即可“扩展”。它不是包括它。

在Rails上,这个习惯用法已经过时,你应该使用ActiveSupport :: Concern。

答案 1 :(得分:1)

当通过ruby中的模块包含类方法和实例方法时,这里使用的模式很常见。它为您提供了必须编写

的优势
include ExampleModule

包含实例方法和扩展类方法而不是

# include instance methods
include ExampleModule
# extend class methods
extend ExampleModule::ClassMethods

因此,如果仅用于使用某些方法扩展类,我个人的偏好是直接使用extend

module ExtensionAtClassLevel
  def bla
    puts 'foo'
  end
end

class A
  extend ExtensionAtClassLevel
end

A.bla #=> 'foo'

如果添加了实例和类方法,我使用你描述的include钩子。

有些rubyists倾向于使用include钩子来扩展pure extend,如果你只是添加类例子中的类方法,这是没有理由的。