模块与Mix-in

模块是什么?

  • 模块不能拥有实例
  • 模块不能被继承

模块的使用

# 检查文件是否存在
p FileTest.exist?("/usr/bin/ruby")
#=> true

# 圆周率
p Math::PI

#包含Math模块,这样就可以直接使用了
include Math
p PI

模块的定义

module HelloModule
  Version = "1.0"

  def hello(name)
    p "hello, #{name}."
  end

  # 把方法曝露给外部使用
  module_function :hello
end

#均成功
HelloModule.hello "Aaron"
p HelloModule::Version

#均成功
include HelloModule
hello "Aaron"
p Version

Mix-in

module HelloModule
  def hello(name)
    p "hello, #{name}."
  end
end

class Test
  include HelloModule
end

test = Test.new
test.hello "Aaron"
#=> 成功

#判断是否包含某个模块
p Test.include? HelloModule
#=> true

#继承关系列表
p Test.ancestors
#=> [Test, HelloModule, Object, Kernel, BasicObject]

#父类
p Test.superclass
#=> Object

Mix-in查找原则

  • 同继承关系一样,原类中已经定义了同名的方法,优先使用类中的
  • 在同一个类中多次包含多个模块,优先使用最后一个
  • 嵌套include时,查找顺序也是线性的

extend方法

另一种单例方法的定义

module HelloModule
  def hello(name)
    p "hello, #{name}."
  end
end

str = "Ruby简明攻略"
str.extend HelloModule
str.hello "Aaron"
#=> 成功

类与Mix-in

  • 在Ruby中,所有类本身都是Class类的对象
  • 类方法就是类对象的实例方法
  • 也是Class类的实例方法
  • 类对象的单例方法
  • 继承类后,这些方法就会作为类方法被子类继承
  • 对子类定义单例方法,实际上也就是定义新的类方法

什么跟什么嘛,我先理解理解的。。。

module ClassMethods
    def cmethod
        "class method"
    end
end

module InstanceMethods
    def imethod
        "instance method"
    end
end

class MyClass
    #定义类方法
    extend ClassMethods

    #定义实例方法
    include InstanceMethods
end

p Myclass.cmethod
p Myclass.new.imethod