模块(module)是一种把方法、类和常量组合在一起的方式。模块(module)为您提供了两大好处。
模块(module)定义了一个命名空间,相当于一个沙盒,在里边您的方法和常量不会与其他地方的方法常量冲突。
模块类似与类,但有一下不同:
module identifier statement1 statement2 ........... end
模块常量命名与类常量命名类似,以大写字母开头。方法定义看起来也相似:模块方法定义与类方法定义类似。
通过类方法,您可以在类方法名称前面放置模块名称和一个点号来调用模块方法,您可以使用模块名称和两个冒号来引用一个常量。
#!/usr/bin/ruby # 定义在 trig.rb 文件中的模块 module trig pi = 3.141592654 def trig.sin(x) # .. end def trig.cos(x) # .. end end
我们可以定义多个函数名称相同但是功能不同的模块:
#!/usr/bin/ruby # 定义在 moral.rb 文件中的模块 module moral very_bad = 0 bad = 1 def moral.sin(badness) # ... end end
就像类方法,当您在模块中定义一个方法时,您可以指定在模块名称后跟着一个点号,点号后跟着方法名。
require 语句类似于 c 和 c++ 中的 include 语句以及 java 中的 import 语句。如果一个第三方的程序想要使用任何已定义的模块,则可以简单地使用 ruby require 语句来加载模块文件:
require filename
在这里,文件扩展名 .rb 不是必需的。
$load_path << '.' require 'trig.rb' require 'moral' y = trig.sin(trig::pi/4) wrongdoing = moral.sin(moral::very_bad)
在这里,我们使用 $load_path << '.' 让 ruby 知道必须在当前目录中搜索被引用的文件。如果您不想使用 $load_path,那么您可以使用 require_relative 来从一个相对目录引用文件。
注意:在这里,文件包含相同的函数名称。所以,这会在引用调用程序时导致代码模糊,但是模块避免了这种代码模糊,而且我们可以使用模块的名称调用适当的函数。
您可以在类中嵌入模块。为了在类中嵌入模块,您可以在类中使用 include 语句:
include modulename
如果模块是定义在一个单独的文件中,那么在嵌入模块之前使用 require 语句引用该文件时必需的。
假设下面的模块写在 support.rb 文件中。
module week first_day = "sunday" def week.weeks_in_month puts "you have four weeks in a month" end def week.weeks_in_year puts "you have 52 weeks in a year" end end
现在,您可以在类中引用该模块,如下所示:
#!/usr/bin/ruby $load_path << '.' require "support" class decade include week no_of_yrs=10 def no_of_months puts week::first_day number=10*12 puts number end end d1=decade.new puts week::first_day week.weeks_in_month week.weeks_in_year d1.no_of_months
这将产生以下结果:
sunday you have four weeks in a month you have 52 weeks in a year sunday 120
在阅读本节之前,您需要初步了解面向对象的概念。
当一个类可以从多个父类继承类的特性时,该类显示为多重继承。
ruby 不直接支持多重继承,但是 ruby 的模块(module)有另一个神奇的功能。它几乎消除了多重继承的需要,提供了一种名为 mixin 的装置。
mixins 向您提供了一种完美的为类添加功能的控制方式。但是,它们真正的强大在于当 mixin 中的代码开始与使用它的类中的代码交互时。
让我们看看下面的示例代码,深入了解 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