1

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

我正在阅读一些关于模块的教程,它们看起来有点类似于静态类。我难以理解的一点是为什么你会做如下的事情:

module ExampleModule

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

  module ClassMethods
      def myMethod
      end
  end
end

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

4

2 回答 2

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。

于 2013-01-30T14:20:32.213 回答
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'

如果同时添加了实例和类方法,我将使用您描述的包含挂钩。

一些 ruby​​ists 倾向于通过 include 钩子来使用 extend 到 pure extend,如果您只是像示例中那样添加类方法,这是没有理由的。

于 2013-01-30T14:21:10.623 回答