Ruby模块与Mixin #

一、模块概述 #

模块是Ruby中组织代码的重要方式,用于命名空间和Mixin。

二、定义模块 #

2.1 基本语法 #

ruby
module MyModule
  CONSTANT = "value"

  def self.module_method
    "Module method"
  end

  def instance_method
    "Instance method"
  end
end

MyModule::CONSTANT
MyModule.module_method

2.2 模块作为命名空间 #

ruby
module Graphics
  class Point
    attr_reader :x, :y

    def initialize(x, y)
      @x, @y = x, y
    end
  end

  class Rectangle
    attr_reader :width, :height

    def initialize(width, height)
      @width, @height = width, height
    end
  end
end

point = Graphics::Point.new(10, 20)
rect = Graphics::Rectangle.new(100, 200)

2.3 嵌套模块 #

ruby
module App
  module Models
    class User
    end
  end

  module Controllers
    class UsersController
    end
  end
end

user = App::Models::User.new
controller = App::Controllers::UsersController.new

三、include #

3.1 基本用法 #

ruby
module Greeting
  def greet
    "Hello!"
  end
end

class Person
  include Greeting
end

person = Person.new
person.greet

3.2 方法查找顺序 #

ruby
module A
  def method_name
    "A"
  end
end

class B
  include A

  def method_name
    "B"
  end
end

B.new.method_name

class B
  def method_name
    super + " + B"
  end
end

B.new.method_name

3.3 多个include #

ruby
module A
  def test
    "A"
  end
end

module B
  def test
    "B"
  end
end

class C
  include A
  include B
end

C.new.test
C.ancestors

四、extend #

4.1 基本用法 #

ruby
module ClassMethods
  def class_method
    "Class method"
  end
end

class Person
  extend ClassMethods
end

Person.class_method

4.2 同时添加类方法和实例方法 #

ruby
module Mixin
  def instance_method
    "Instance method"
  end

  module ClassMethods
    def class_method
      "Class method"
    end
  end
end

class Person
  include Mixin
  extend Mixin::ClassMethods
end

Person.class_method
Person.new.instance_method

4.3 self.included钩子 #

ruby
module Mixin
  def instance_method
    "Instance method"
  end

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

  module ClassMethods
    def class_method
      "Class method"
    end
  end
end

class Person
  include Mixin
end

Person.class_method
Person.new.instance_method

五、prepend #

5.1 基本用法 #

ruby
module Override
  def greet
    "Override: " + super
  end
end

class Person
  prepend Override

  def greet
    "Hello!"
  end
end

Person.new.greet
Person.ancestors

5.2 prepend vs include #

ruby
module A
  def test
    "A -> " + super
  end
end

class B
  include A

  def test
    "B"
  end
end

B.new.test

class C
  prepend A

  def test
    "C"
  end
end

C.new.test

六、module_function #

6.1 基本用法 #

ruby
module Math
  module_function

  def square(n)
    n ** 2
  end

  def cube(n)
    n ** 3
  end
end

Math.square(5)
Math.cube(3)

class Calculator
  include Math
end

Calculator.new.square(4)

6.2 混合使用 #

ruby
module Helper
  def public_method
    "Public"
  end

  module_function

  def utility_method
    "Utility"
  end
end

七、实用示例 #

7.1 可比较模块 #

ruby
module Comparable
  def <(other)
    (self <=> other) < 0
  end

  def <=(other)
    (self <=> other) <= 0
  end

  def ==(other)
    (self <=> other) == 0
  end

  def >(other)
    (self <=> other) > 0
  end

  def >=(other)
    (self <=> other) >= 0
  end
end

class Point
  include Comparable

  attr_reader :x, :y

  def initialize(x, y)
    @x, @y = x, y
  end

  def <=>(other)
    [x, y] <=> [other.x, other.y]
  end
end

7.2 可枚举模块 #

ruby
module Enumerable
  def map
    result = []
    each { |item| result << yield(item) }
    result
  end

  def select
    result = []
    each { |item| result << item if yield(item) }
    result
  end

  def reduce(initial = nil)
    accumulator = initial
    each do |item|
      accumulator = accumulator.nil? ? item : yield(accumulator, item)
    end
    accumulator
  end
end

7.3 日志模块 #

ruby
module Loggable
  def log(message)
    puts "[#{self.class}] #{message}"
  end

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

  module ClassMethods
    def log_class(message)
      puts "[#{self}] #{message}"
    end
  end
end

class User
  include Loggable

  def save
    log("Saving user")
  end
end

User.new.save
User.log_class("Created")

7.4 缓存模块 #

ruby
module Cacheable
  def cached(key)
    @cache ||= {}
    return @cache[key] if @cache.key?(key)

    @cache[key] = yield
  end

  def clear_cache
    @cache&.clear
  end
end

class ExpensiveService
  include Cacheable

  def compute(n)
    cached(n) do
      puts "Computing..."
      sleep 1
      n ** 2
    end
  end
end

service = ExpensiveService.new
service.compute(5)
service.compute(5)

八、模块最佳实践 #

8.1 命名空间组织 #

ruby
module MyApp
  module Models
    class User
    end
  end

  module Services
    class UserService
    end
  end

  module Repositories
    class UserRepository
    end
  end
end

8.2 Mixin设计原则 #

ruby
module Swimmable
  def swim
    "Swimming"
  end
end

module Flyable
  def fly
    "Flying"
  end
end

class Duck
  include Swimmable
  include Flyable
end

duck = Duck.new
duck.swim
duck.fly

8.3 避免模块污染 #

ruby
module SafeModule
  def self.included(base)
    base.send(:define_method, :safe_method) do
      "Safe method"
    end
  end
end

九、总结 #

本章我们学习了:

  1. 模块定义:命名空间、嵌套模块
  2. include:添加实例方法、方法查找顺序
  3. extend:添加类方法
  4. prepend:方法包装、super调用
  5. module_function:模块函数
  6. 实用模式:Comparable、Enumerable、Loggable

接下来让我们学习Ruby的封装!

最后更新:2026-03-27