module - 複数のクラスで使用する部品
モジュールを作る
モジュールの定義は下記のようにして行う。
module ModuleName
end
クラスの記述と似ているがインスタンスを作ることはできなず、
主にメソッドを複数クラスで共同利用するための部品として使用する。
モジュール内ではメソッドの他に定数やクラス、モジュールの定義が可能。
メソッドを定義
例えばUserクラスやAnimalクラスが共通で使えるintroduce
メソッドを用意してみる。
module Introduce
def introduce
puts "私は#{@name}です"
end
end
include - モジュールをクラスで使用する
まずはUserクラスとAnimalクラスを作ります
class User
def initialize(name)
@name = name
end
end
class Animal
def initialize(name)
@name = name
end
end
クラス内でモジュールを使用するにはinclude
を使用して、
引数に使用したいモジュール名を指定します。
include
は何度でも呼べるため1つのクラス内で複数のモジュールが使用可能。
class User
include Introduce
def initialize(name)
@name = name
end
end
class Animal
include Introduce
def initialize(name)
@name = name
end
end
user = User.new("tarou")
user.introduce
cat = Animal.new("猫")
cat.introduce
私はyumです
私は猫です
include
で取り込んだモジュールはクラスのインスタンスメソッドとして利用できる。
そのため呼び出しの際のレシーバーはインスタンスとなる。
extend - モジュールをクラスメソッドとして利用する
extend
を使用した場合はモジュールメソッドがクラスメソッドとして定義される。
module Greeting
def hello
puts "こんにちは"
end
end
class User
extend Greeting
def initialize(name)
@name = name
end
end
class Animal
extend Greeting
def initialize(name)
@name = name
end
end
User.hello
Animal.hello
こんにちは
こんにちは
クラスメソッド
モジュールにはクラス同様にクラスメソッドを定義することができる。
呼び出し方法もクラスメソッドと同様。
module Greeting
def introduce
puts "こんにちは"
end
def self.info
"挨拶を行うモジュールです"
end
end
Greeting.info
挨拶を行うモジュールです
クラスメソッドが複数行になる場合もクラス同様にclass << self
end
内に記述すればOK。
module Greeting
def hello
puts "こんにちは"
end
class << self
def info
puts "挨拶を行うモジュールです"
end
def english
puts "Hello"
end
end
end
Greeting.info
Greeting.english
挨拶を行うモジュールです
Hello
定数
モジュール内には定数を用意しておくことも可能。
定数の場合は呼び出し時が異なり、モジュール名::定数
で使用する。
module Greeting
#何も思い浮かばず...Greetingの文字数としてCharsにしてみた。
Chars = 8
end
puts Greeting::Chars
8
組み込みモジュール
Rubyが既に用意してくれているモジュールもいくつかあります。
よく使うものでMath
や、Array、Hashクラス内で使用しているEnumerable
モジュールなど。
# 円周率を保持した定数PI
puts Math::PI
# cosinを計算する際に使用するcosメソッド
puts Math.cos(Math::PI)
3.141592653589793
-1.0
名前空間
開発が大規模になってくると同じクラス名を使用したい場面などが出てくる。
そんな時にmodule
を名前空間として使用することでクラス名の重複を避けることができる。
module StarBucks
class Coffee
def self.info
puts "アメリカ発祥のコーヒーショップです"
end
end
end
module Doutor
class Coffee
def self.info
puts "日本発祥のコーヒーショップです"
end
end
end
StarBucks::Coffee.info
Doutor::Coffee.info
アメリカ発祥のコーヒーショップです
日本発祥のコーヒーショップです
上記のようにモジュール内にクラスを定義して、
呼び出す際にはmodule名::クラス名
とする。
名前空間を使用することでCoffeeというクラス名を複数使用できるようになる。
ちなみにプログラムで一番外側(トップレベル)に書かれているモジュールやクラスは先頭に::
をつけて、
::モジュール名
::クラス名
のように呼び出すこともできる。
::StarBucks::Coffee.info
::Doutor::Coffee.info
アメリカ発祥のコーヒーショップです
日本発祥のコーヒーショップです
最後に
モジュールはよく使うメソッドを部品として一つの箱に用意しておくイメージ。
継承はしたくないけど他のクラスでも使えそうだな...
そんな時にモジュールとして切り出しておくと余計な記述を減らせたり、読みやすいコードがかけるのではないでしょうか。