Rubyの便利な機能の一つに、「モジュール」があります。
Rubyでは、オブジェクト指向プログラミングの基本となるクラスとそこから生成されるインスタンスの組み合わせに加えて、モジュールという特徴的な機能が用意されており、より柔軟にプログラムが書けるようになっています。
Rubyにおけるモジュールの基本
モジュールの書き方
1 2 3 |
module モジュール名 処理 end |
モジュール名の制限
モジュール名は必ず英数字の大文字で始めます。以下はエラーになります。
1 2 3 4 |
module hello puts "hello" end #=> SyntaxError: class/module name must be CONSTANT |
大文字で始めればOKです。
1 2 3 |
module Hello puts "hello" end |
モジュールとクラスの違い
モジュールは一見、クラスとよく似ています。クラスはデータと処理を一つにまとめたものですが、モジュールはクラスと違って、「処理」だけをまとめたものになります。
もっとはっきりしたクラスとの違いをまとめると、以下の2点になります。
- モジュールはインスタンスを作れない
- モジュールは継承できない
モジュールを使う目的
モジュールは、4つの目的によく使われます。
- 名前空間の提供
- インスタンスメソッドとして取り込む(Mix-in)
- モジュールをオブジェクトに取り込む(extend)
- モジュール関数
次から、4つのモジュールの使い方について説明します。
1. モジュールをつかった名前空間の提供
プログラムを書いていると、モジュール名やクラス名の被りがでてきますが、この名前空間を使うことで名前の被りを回避できます。名前空間とは、クラスとモジュールを名前をつけて分けるための容れ物やタグのようなものです。
呼び出しは、::演算子を使い「モジュール名::モジュール名」または「モジュール名::クラス名」のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
module Person class Student def self.say puts "I'm a student." end end end class Student def self.say puts "私は学生です" end end Person::Student.say #=> "I'm a student." Student.say #=> 私は学生です |
上の例では、Studentクラスが2つ存在していますが、Personモジュールを名前空間として使っているので、名前の衝突が起きません。
2. インスタンスメソッドとして取り込む(Mix-in)
Mix-inはRuby独特の機能です。Rubyのクラスは、他の言語でいう多重継承を基本的に許さず、そのかわりにMix-inという仕組みを用意しています。これに使われるのがモジュールです。
Mix-inを使ってincludeされたモジュールのメソッドは、クラスのインスタンスメソッドになります。
以下の例では、GoodMorningとGoodNightという2つのモジュールをincludeしたGreetクラスを作成しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
module GoodMorning def sayGoodMorning puts "Good Morning" end end module GoodNight def sayGoodNight puts "Good Night" end end class Greet include GoodMorning, GoodNight end obj = Greet.new obj.sayGoodMorning #=> Good Morning obj.sayGoodNight #=> Good Night |
このように、共通のする処理を切り出し、必要な機能だけをクラスに持たせることができます。
3. モジュールをオブジェクトに取り込む(extend)
また、モジュールに定義されたメソッドはオブジェクトのインスタンスに、特異メソッドとして取り込むこともできます。
以下では、空のオブジェクトにextendを使ってGreetモジュールのメソッドを追加しています。
1 2 3 4 5 6 7 8 9 |
module Greet def say puts "Hello" end end obj = Object.new obj.extend Greet obj.say |
クラスメソッドとして取り込む
また、extendはクラス定義内でも使用でき、取り込まれたモジュールのメソッドはクラスメソッドとなります。
1 2 3 4 5 6 7 8 9 10 11 |
module Greet def say puts "Hello" end end class Person extend Greet end Person.say |
4. モジュール関数
Mathモジュールで使用するメソッドは、Rubyの組み込みモジュール関数として定義されています。
モジュール関数は以下のように、「module_function :メソッド名」と記述します。
1 2 3 4 5 6 |
module Greet def hello puts "Hello!" end module_function :hello end |
モジュール関数の呼び出し
モジュール関数の呼び出しは、includeを使う場合とモジュールを指定する場合の2つがあります。
includeを使う場合は以下のようになります。
1 2 |
include Greet hello |
モジュールを指定する場合は以下のようになります。
1 |
Greet.hello |