Ruby 模組(Module)


模組(Module)是一種把方法、類別和常數組合在一起的方式。模組(Module)為您提供了兩大好處。

  • 模組提供了一個命名空間和避免名字衝突。

  • 模組實作了 mixin 裝置。

模組(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

就像類別方法,當您在模組中定義方法時,您可以指定在模組名稱後面跟著一個點號,點號後面跟著方法名稱。

Ruby require 語句

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 來從一個相對目錄引用檔案。

注意:在這裡,檔案包含相同的函數名稱。所以,這會在引用呼叫程式時導致程式碼模糊,但是模組避免了這種程式碼模糊,而且我們可以使用模組的名稱來呼叫適當的函數。

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 中的Mixins

在閱讀本節之前,您需要初步了解物件導向的概念。

當一個類別可以從多個父類別繼承類別的特性時,該類別顯示為多重繼承。

Ruby 不直接支援多重繼承,但是 Ruby 的模組(Module)有另一個神奇的功能。它幾乎消除了多重繼承的需要,提供了一個名為 mixin 的裝置。

Ruby 沒有真正實作多重繼承機制,而是採用成為mixin技術作為替代品。將模組include到類別定義中,模組中的方法就mix進了類別中。

讓我們看看下面的範例程式碼,深入了解 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