LoginSignup
1
2

More than 3 years have passed since last update.

【Ruby】モジュールとは?クラスの違いについて。モジュールの中のメソッドの呼び出し方

Posted at

Rubyのモジュールとクラスの違いについて。モジュールの中のメソッドの呼び出し方実例と注意点。

目次

  1. モジュールとは?
  2. モジュールのメリット
    1. メリット1 複数継承可能
    2. メリット2 同じメソッド名を定義できる
  3. モジュールの呼び出し方法
    1. classの中で読み込む
    2. moduleの中でmodule_functonを定義する
    3. Objectとextendを使う
    4. NG事例
  4. mixinとは?

モジュールとは?

  • メソッドを記述しておく場所
  • moduleの中にdefでメソッドを書いていく
  • メソッドを複数定義できる
module <モジュール名>
  def <メソッド名1>
    処理1
  end

  def <メソッド名2>
    処理2
  end
  ,
  ,
  ,
end


モジュールのメリット

  1. 複数読み込み可能
  2. 同じメソッド名を定義できる

メリット1 複数継承可能

複数のクラスを継承したい(メソッドの書かれた複数のファイルを読み込みたい)場合の代替手段。

▼どういうこと?
Rubyのデメリットとして、クラスを一つしか継承できない(単一継承)がある。

このため、他のクラスを読み込んで、更に既に定義したメソッドを読み込みたい場合に、他のクラスを読み込むことができない。

この解決手段としてモジュールがある。モジュールを使えば、継承するクラスの他にもメソッドを読み込むことができるようになる


メリット2 同じメソッド名を定義できる

module自体の名前が異なれば、同じメソッドでも違う名前になる。(オブジェクトのKVと同じ。)

オブジェクトの場合
obj1 = {name: yamada, age: 24}
obj2 = {name: tanaka, age: 24}

#呼び出し
obj1.name  #yamada
obj2.name  #tanaka

nameという同じプロパティ名が存在するが、大元がobj1とobg2で異なるため、違う扱いになる。

▼モジュールの場合

module
module Aaa
  def hello
    p "こんにちは"
  end
end

module Bbb
  def hello
    p "ニーハオ"
  end
end

メソッド名はどちらもhelloだが、入れ物が異なるので問題ない。


モジュールの呼び出し方法

モジュールの呼び出し方法は2つ。

  1. classの中で読み込む
  2. moduleの中でmodule_functonを定義する
  3. Objectとextendを使う

1. classの中で読み込む

include <モジュール名>で読み込む
<クラス名>.new.<メソッド名>で実行する

メソッドの実行方法は、通常のクラスと同じくインスタンスを作成して、メソッドを呼び出す。

OK
#モジュールの定義
module Aaa
  def hello
    p "こんにちは"
  end
end

#クラスで読み込み
class Xxx
  include Aaa
end

#メソッドの実行
Xxx.new.hello

 => "こんにちは"

モジュールが複数ある場合

カンマで繋ぐ。

include <モジュール名1>, <モジュール名1>,,,

▼注意点
メソッド名が同じ場合は、上のモジュールのメソッドが読み込まれる。(下側は無視される)

OK(メソッド名が同じ場合)
#モジュールの定義
module Aaa
  def hello
    p "こんにちは"
  end
end

module Bbb
  def hello
    p "ニーハオ"
  end
end

#クラスで読み込み
class Xxx
  include Bbb, Aaa
end

#メソッドの実行
Xxx.new.hello

=> "こんにちは"

mixinとは?

クラスの中でmoduleを呼び出すことをmixin(ミクシン)と呼ぶ。

mixinというメソッドがあるわけではなく、classの中でincludeを使ってmoduleを呼び出すこと = mixinとなる。

<を継承と呼ぶのと同じく、ただの名称。


2. moduleの中でmodule_functonを定義する

module_function :<メソッド名>

▼注意点
- :の後にスペースを空けない(エラーになる)
- 記述するメソッドは一つずつ。(メソッドが複数ある場合は複数記述する。カンマでつなげない)

OK
#モジュールの定義
module Aaa
  def hello
    p "こんにちは"
  end

  module_function:hello
end

#メソッドの実行
Aaa.hello

 => "こんにちは"


3. Objectとextendを使う

Object.newで空のオブジェクトを生成し、.extend <モジュール名>で拡張すれば、メソッドが使用できる。

OK
#モジュールの定義
module Aaa
  def hello
    p "こんにちは"
  end
end

#オブジェクトの生成
obj = Object.new

#モジュールの拡張
obj.extend Aaa

#メソッドの呼び出し
obj.hello
 => "こんにちは"


NG事例

モジュールはクラスの中で定義した関数のように、<モジュール名>.new.<メソッド名>では呼び出せない。

NG
#モジュールの定義
module Aaa
  def hello
    p "こんにちは"
  end
end

#メソッドの実行
Aaa.new.hello

#エラー内容
NoMethodError (undefined method `hello' for Aaa:Module)
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2