文章目录
一、模块内有什么
模块是方法、类、常量的组合,它相当于定义了一个命名空间,里面的内容单独有一个空间。以大写字母开头。定义类似Python
module ModuleName
# [VALUE...]
# [Class...]
# [def...]
end
Ⅰ、定义常量
直接定义常量
# TestModule.rb
module TestModule
VALUE = 1
end
Ⅱ、定义方法
为了能从外部调用,方法必须命名为module.function
# TestModule.rb
module TestModule
def TestModule.testfunction
puts 1
end
end
如果不是为了调用,而是为了引入成为类方法,则不需要module
见四
# TestModule.rb
module TestModule
def testfunction
puts 1
end
end
Ⅲ、定义类
直接定义类
# TestModule.rb
module TestModule
class TestClass
def initialize(a)
@a = a
end
def testfunction
puts @a
end
end
end
二、导入模块
类似Python的import和C的include,Ruby使用require
导入模块
导入自定义模块之前需要添加$LOAD_PATH << '.'
指明只能从当前路径,要么就是用require_relative 相对路径
,不指定路径时导入公用模块。扩展名可省略
可以在任何地方导入模块、导入多个模块
$LOAD_PATH << '.'
require 'Module'
require 'Module.rb'
require_relative 'Module'
三、调用模块
Ⅰ、调用常量
使用module::const
调用常量
# TestModule.rb
module TestModule
VALUE = 1
end
require_relative 'TestModule'
puts TestModule::VALUE
Ⅱ、调用方法
使用module.function
调用模块内方法
# TestModule.rb
module TestModule
def TestModule.testfunction
puts 1
end
end
require_relative 'TestModule'
TestModule.testfunction
Ⅲ、实例化类并调用类方法
使用module::class.new(args)
实例化类,模块类算作静态常量
# TestModule.rb
module TestModule
class TestClass
def initialize(a)
@a = a
end
def testfunction
puts @a
end
end
end
require_relative 'TestModule'
testclass = TestModule::TestClass.new(1)
testclass.testfunction
四、在类中嵌入模块
Ruby支持使用include module
将模块镶嵌到类中,使得实例化类可以使用模块,注意定义方法不能指定模块名
可以在类内任何地方嵌入模块、嵌入多个模块
# IncludeModule.rb
module IncludeModule
VALUE = 1
def hello
puts "hello"
end
end
require_relative 'IncludeModule'
class A
include IncludeModule
end
puts A::VALUE
a = A.new
a.hello
1
hello
嵌入模块时的覆盖问题
类嵌入模块遇到同名常量、方法时会有覆盖问题
①、类定义优先
只要类定义了同名常量、方法,按类优先处理,不会覆盖
常量:
# IncludeModule.rb
module IncludeModule1
VALUE = 1
end
module IncludeModule2
VALUE = 2
end
require_relative 'IncludeModule'
class A
include IncludeModule1
VALUE = 0
include IncludeModule2
end
puts A::VALUE
0
方法:
# IncludeModule.rb
module IncludeModule1
def hello
puts "hello1"
end
end
module IncludeModule2
def hello
puts "hello2"
end
end
require_relative 'IncludeModule'
class A
include IncludeModule1
def hello
puts 'hello0'
end
include IncludeModule2
end
a = A.new
a.hello
hello0
②、最后嵌入优先
支持嵌入多个模块,最后嵌入模块中的同名方法、常量被保留
常量:
# IncludeModule.rb
module IncludeModule1
VALUE = 1
end
module IncludeModule2
VALUE = 2
end
require_relative 'IncludeModule'
class A
include IncludeModule1
include IncludeModule2
end
puts A::VALUE
2
方法:
# IncludeModule.rb
module IncludeModule1
def hello
puts "hello1"
end
end
module IncludeModule2
def hello
puts "hello2"
end
end
require_relative 'IncludeModule'
class A
include IncludeModule1
include IncludeModule2
end
a = A.new
a.hello
hello2
五、Mixins
Ruby没有继承的概念,如果一个类需要“继承父类方法”,将“父类方法”写入module,使用include嵌入
将模块include到类定义中,模块中的方法就mix进了类中。
类 Sample 继承了两个模块、类 Sample 使用了多重继承或 mixin 。
module A
def a1
end
def a2
end
end
module B
def b1
end
def b2
end
end
class Sample
include A
include B
def s1
end
end
samp=Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1