LoginSignup
1
0

More than 1 year has passed since last update.

モジュールについてまとめてみた

Last updated at Posted at 2022-03-05

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モジュールなど。

Math
# 円周率を保持した定数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
アメリカ発祥のコーヒーショップです
日本発祥のコーヒーショップです

最後に

モジュールはよく使うメソッドを部品として一つの箱に用意しておくイメージ。
継承はしたくないけど他のクラスでも使えそうだな...
そんな時にモジュールとして切り出しておくと余計な記述を減らせたり、読みやすいコードがかけるのではないでしょうか。

1
0
3

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
0