Ruby 模块和Mixin

模块是ruby的特色功能之一,除了提供代码级别的命名空间用于解决区分和冲突的问题,它能提供给我们另一个维度上的代码复用,弥补单继承的一些限制,有点像自带实现的接口,无副作用的添加一些实用的功能,整体概括起来大概就是:

  • 提供命名空间
    A.foo vs B.foo
  • Mixin扩展功能
    弥补单继承,给类提供通用的功能;提供类似于其它语言中接口表示的can-do的功能,只不过在ruby里面模块已经自带实现,开箱即用。

命名空间的功能非常好理解,在代码量上来或者使用外部包众多的时候需要相应的途径保持合理组织或解决冲突。
相比,mixin所提供的功能更佳有趣,ruby里面最经典的一处使用大概就是Enumerable了吧,以后也会慢慢讲到。

先来看一个例子:

module M
  def meth
    "meth"
  end
end

class C
  include M
end

c = C.new
p c.meth     #=> meth

p C.ancestors       #=> [C, M, Object, Kernel, BasicObject]

在这里通过inlcude模块我们添加的相当于是类型C的实例方法,通过调用的方式也能证明,反过来想,类本省其实也是一个对象,类的方法其实可以对等于把类本身当作"实例"对象的方法,借助于ruby提供的Object#extend方法,通过mixin的方式也能非常方便批量提供复用的类方法:

module ClassMethods
  def cmethod
    "class method"
  end
end

class MyClass
  extend ClassMethods
end

p MyClass.cmethod        #=> "class method"

通过打出的日志可以看到,通过mixin的方式成功添加了一个类方法cmethod

Ruby在使用mixin的功能的时候,方法的查找顺序是非常简单的线性查找:

module M1
end

module M2
end

module M3
  include M2
end

class C
  include M1
  include M3
end

p C.ancestors       #=> [C, M3, M2, M1, Object, Kernel, BasicObject]


作者:TypingQuietly
链接:http://www.jianshu.com/p/c923f15ee3cf
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2017-07-31 12:29  天涯海角路  阅读(653)  评论(0)    收藏  举报