モジュールについてわからなすぎたので、簡単にまとめます。
参考文献
「プロを目指す人のためのRuby入門」
こちらを読みながら、わかったことをまとめます。
モジュールとは
モジュールは、Rubyにおけるコードを整理・グループ化する仕組み。
主に下記の3つのことができる。
- 1. 継承を使わずに、メソッドを使用できる(include・Mix-in)。
- 2. モジュール内のメソッドをクラスメソッドとして追加する(extend)。
- 3. モジュールを名前空間として使い、クラスやメソッドの衝突を防ぐ。(名前空間=name_space)
1. Mix-in
継承を使わずにメソッドを共有する仕組み。
Rubyは単一クラス(スーパークラス)しかない。
# ユーザーを表すクラス
class User
# 省略
end
# 注文を表すクラス
class Order
# 省略
end
ユーザクラスと注文クラス内に同じコードがあったとしても、
この2つのクラスはis-a
関係(〜は〜である)でないので、継承できない。
⇒ Mix-in(include)を使えば解決する。
# ログ機能を提供するモジュール
module Logger
# 下記がユーザ・注文どちらのクラスでも書かれてるので、モジュール内に書く
def log(message)
puts "[LOG] #{message}"
end
end
# ユーザーを表すクラス
class User
# Mix-in
# コード繰り返し書く必要なくなる
include Logger
end
# 注文を表すクラス
class Order
# Mix-in
# コード繰り返し書く必要なくなる
include Logger
end
また、 include
だと インスタンスメソッド
として追加される。
インスタンスメソッド
とは:
インスタンスに属するメソッドで、インスタンスを生成しないと使えない。
「インスタンス」
:
クラスから作成する1個の個体・実体。
「.new」でクラスから、新しいインスタンスを作成する。
「メソッド」
:
そのクラスでやりたいこと。処理のまとまり。
何回もコードを書かなくて済むように、クラス内に書いて、
他のインスタンス(個体)にも同じ処理をさせる。
2. extend
モジュール内のメソッドを
クラスそのものをメソッドとして(クラスメソッド)追加される。
クラスメソッド
とは
クラスに属するメソッドで、インスタンスを生成せずに直接クラスから使える。
includeとの違い
# モジュールの定義
module Greeting
def say_hello
"こんにちは!"
end
end
#################################################
# 【include】を使用したクラス
class User
# インスタンスメソッドとして追加
include Greeting
end
# 【include】:インスタンスメソッドを呼び出せる
# つまり、インスタンス経由でメソッドを呼び出す
user = User.new # インスタンスを生成
puts user.say_hello
#################################################
# 【extend】を使用したクラス
class Admin
# クラスメソッドとして追加
extend Greeting
end
# 【extend】:クラスでメソッドを呼び出せる
# つまり、クラスそのものでメソッドを呼び出す(インスタンスメソッド不要)
puts Admin.say_hello # => "こんにちは!" (クラスメソッド)
操作 | 取り込まれる場所 | 呼び出し元 | 結果 |
---|---|---|---|
include |
クラスのインスタンス | インスタンス(User.new ) |
インスタンスメソッド |
extend |
クラスそのもの(特異クラス) | クラス(Admin ) |
クラスメソッド |
3. 名前空間(name_space)
クラス名がかぶってしまった時、そのモジュールに属するクラスにすることで、
他のプログラム・ライブラリと、クラス名やメソッド名の衝突を防ぐことができる。
module Admin
# Adminモジュールに属するクラスなので、
# クラス名Userが被ってても、区別できる。
class User
def role
"管理者"
end
end
end
module Guest
# Guestモジュールに属するクラスなので、
# クラス名Userが被ってても、区別できる。
class User
def role
"ゲスト"
end
end
end
# 動作確認
admin_user = Admin::User.new
guest_user = Guest::User.new
puts admin_user.role # => "管理者"
puts guest_user.role # => "ゲスト"