Ruby - 模块和混合

模块是将方法、类和常量组合在一起的一种方式。 模块为您带来两大好处。

  • 模块提供命名空间并防止名称冲突。

  • 模块实现 mixin 工具。

模块定义了一个命名空间,一个沙箱,您的方法和常量可以在其中发挥作用,而不必担心被其他方法和常量踩到。


语法

module Identifier
   statement1
   statement2
   ...........
end

模块常量的命名与类常量一样,首字母大写。 方法定义看起来也很相似:模块方法的定义就像类方法一样。

与类方法一样,通过在模块名称前加上模块名称和句点来调用模块方法,并使用模块名称和两个冒号引用常量。

示例

#!/usr/bin/ruby

# Module defined in trig.rb file

module Trig
   PI = 3.141592654
   def Trig.sin(x)
   # ..
   end
   def Trig.cos(x)
   # ..
   end
end

我们可以再定义一个具有相同功能名称但功能不同的模块 −

#!/usr/bin/ruby

# Module defined in moral.rb file

module Moral
   VERY_BAD = 0
   BAD = 1
   def Moral.sin(badness)
   # ...
   end
end

与类方法一样,每当您在模块中定义方法时,都要指定模块名称,后跟一个点,然后是方法名称。


Ruby 要求声明

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 来包含来自相对目录的文件。

IMPORTANT − 在这里,两个文件都包含相同的函数名。 因此,这将导致在调用程序中包含代码歧义,但模块避免了这种代码歧义,我们能够使用模块名称调用适当的函数。


Ruby include 语句

您可以在类中嵌入模块。 要将模块嵌入到类中,请在类中使用 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 中的 Mixin

在阅读本节之前,我们假设您了解面向对象的概念。

当一个类可以从多个父类继承特性时,该类应该显示多重继承。

Ruby 不直接支持多重继承,但是 Ruby 模块还有另一个奇妙的用途。 一下子,它们几乎消除了对多重继承的需要,提供了一种称为 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

模块 A 由方法 a1 和 a2 组成。 模块 B 由方法 b1 和 b2 组成。 Sample 类包括模块 A 和 B。Sample 类可以访问所有四种方法,即 a1、a2、b1 和 b2。 因此,您可以看到 Sample 类继承自两个模块。 因此,您可以说类 Sample 显示了多重继承或 mixin