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
九、总结 #
本章我们学习了:
- 模块定义:命名空间、嵌套模块
- include:添加实例方法、方法查找顺序
- extend:添加类方法
- prepend:方法包装、super调用
- module_function:模块函数
- 实用模式:Comparable、Enumerable、Loggable
接下来让我们学习Ruby的封装!
最后更新:2026-03-27