1. 什么是模块?
模块(module
)是一组方法和常量的集合,类似于类,但有以下区别:
- 不能实例化:模块无法用
new
创建对象。 - 用途:
- 命名空间:避免命名冲突。
- Mixin:将方法混入类中,实现代码复用。
2. 定义模块
基本语法
module 模块名
# 方法、常量等
end
示例
module Greeting
def say_hello
"你好,世界!"
end
end
- 模块名以大写字母开头(驼峰命名)。
- 定义的方法默认是实例方法。
3. 模块作为命名空间
作用
将相关常量和方法分组,避免命名冲突。
示例
module MathTools
PI = 3.14159
def self.square(n)
n * n
end
end
puts MathTools::PI # 3.14159
puts MathTools.square(5) # 25
注意
- 用
::
访问模块中的常量或模块方法。 self.
定义模块方法(类似类方法)。
4. 模块作为 Mixin
作用
通过 include
或 extend
将模块的方法混入类中。
include
将模块方法作为实例方法混入。
module Greetable
def greet
"你好,我是 #{@name}"
end
end
class Person
include Greetable # 混入模块
def initialize(name)
@name = name
end
end
p = Person.new("张三")
puts p.greet # 你好,我是 张三
extend
将模块方法作为类方法混入。
module Tools
def info
"这是一个工具模块"
end
end
class Calculator
extend Tools # 混入模块作为类方法
end
puts Calculator.info # 这是一个工具模块
组合使用
module Utils
def util_method
"实用方法"
end
end
class Test
include Utils # 实例方法
extend Utils # 类方法
end
t = Test.new
puts t.util_method # 实用方法
puts Test.util_method # 实用方法
5. 模块中的常量
示例
module Config
VERSION = "1.0.0"
AUTHOR = "李四"
end
puts Config::VERSION # 1.0.0
puts Config::AUTHOR # 李四
注意
- 常量可以用
::
访问。 - 常量可以被修改(会发出警告):
Config::VERSION = "2.0.0" # 警告,但有效
6. 嵌套模块
示例
module Outer
module Inner
def say
"嵌套模块方法"
end
end
end
class Demo
include Outer::Inner
end
d = Demo.new
puts d.say # 嵌套模块方法
注意
- 用
::
分隔嵌套层级。 - 嵌套模块常用于组织复杂代码。
7. 中文支持示例
模块名和方法支持中文:
module 问候
def 你好
"你好,大家!"
end
end
class 学生
include 问候
end
s = 学生.new
puts s.你好 # 你好,大家!
8. 实践案例
案例 1:日志模块
module Logger
def log(message)
puts "[#{Time.now}] #{message}"
end
end
class Task
include Logger
def do_work
log("任务开始")
# 工作逻辑
log("任务完成")
end
end
task = Task.new
task.do_work
输出(示例):
[2025-03-22 10:00:00 +0800] 任务开始
[2025-03-22 10:00:00 +0800] 任务完成
案例 2:数学工具
module MathUtils
PI = 3.14159
def self.circle_area(radius)
PI * radius ** 2
end
def square(n)
n * n
end
end
class Shape
include MathUtils
end
puts MathUtils.circle_area(5) # 78.53975
s = Shape.new
puts s.square(4) # 16
案例 3:权限控制
module Permissions
def can_edit?
@role == "admin"
end
end
class User
include Permissions
def initialize(role)
@role = role
end
end
admin = User.new("admin")
guest = User.new("guest")
puts admin.can_edit? # true
puts guest.can_edit? # false
9. include
vs extend
vs prepend
include
- 方法作为实例方法。
- 查找顺序:类方法 > 模块方法。
extend
- 方法作为类方法。
prepend
- 将模块方法插入类的继承链顶部,优先级高于类方法。
module Pre
def say
"来自 Prepend"
end
end
class Example
prepend Pre
def say
"来自类"
end
end
e = Example.new
puts e.say # 来自 Prepend
10. 注意事项
- 不能实例化:模块无法用
new
创建对象。 - 方法冲突:多个模块混入时,后混入的优先级更高(除非用
prepend
)。 - 作用域:模块方法需通过类或
::
调用。
下一步
- 练习:告诉我你想用模块做什么(命名空间、Mixin 等),我可以设计一个例子。
- 问题解答:对模块用法有疑问吗?直接问我!
- 深入学习:想了解模块在 Ruby 标准库或 Rails 中的应用吗?我可以继续讲解。
你现在想做什么?写代码、问问题,还是其他?
发表回复