1. 程式人生 > >Ruby學習之模組(Module)的定義和使用

Ruby學習之模組(Module)的定義和使用

Ruby中的模組(Module)是一種把方法、類和常量組合在一起的方式,它提供了一個名稱空間和避免名字衝突,並且實現了 mixin 裝置。它的名稱空間,相當於一個沙盒,在裡邊我們的方法和常量不會與其他地方的方法常量衝突,它和類很相似,但是它卻不能被例項化,也沒有子類,它只能被另一個模組定義。

語法很簡單:

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語句中,副檔名 .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 語句,如果模組是定義在一個單獨的檔案中,那麼在嵌入模組之前就需要使用 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

Ruby 的類不直接支援多重繼承,但是 Ruby 的模組(Module)有另一個神奇的功能。它幾乎消除了多重繼承的需要,提供了一種名為 mixin 的裝置,但是,Ruby沒有真正實現多重繼承機制,而是採用成為mixin技術作為替代品。將模組include到類定義中,模組中的方法就mix進了類中,來看下例項:


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

好啦,本次記錄就到這裡了。

如果感覺不錯的話,請多多點贊支援哦。。。