3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Ruby】モジュールのミックスインについて

Posted at

#はじめに
今回はRubyのモジュールについてまとめました!
モジュールには様々な用途があります。
主に以下のような用途です。

・クラスにインスタンスメソッドを追加する(ミックスイン)
・クラスにクラスメソッドを追加する(ミックスイン)
・クラス名などの重複を防ぐためにネームスペース(名前空間)を作成する
・ミックスインせずにモジュール単体としてメソッドを定義
など。

最初は何を言ってるか全くわけがわからないと思います。
全ての機能をここで説明するととても長文になってしまうので、今回は上記のうち上から2つ(ミックスイン)に関して説明します。

#モジュールとは
ここで説明する**”ミックスインの機能を持つモジュール”**とは、そもそも何でしょうか。

説明する前に、まずクラスに関してざっとおさらいしておきます。
継承関係にあるクラスは、親クラスのメソッドを子クラスでも呼び出すことが出来ました。
以下がその例です。

test.rb
class User
 def name(name)
  conversation = "hello,#{name}"
 end
end

class Person < User 
end

person = Person.new
person.name("たろう")
#出力結果 ==>"hello,たろう"

親クラスがUserで、子クラスがPersonです。
class Person < UserでUserクラスを継承しています。
その為Personクラスのインスタンスに対して、Userクラスのnameメソッドを呼んだ際に、
ちゃんと"hello,たろう"と返っていることから親クラスのメソッドが使えていることがわかります。

このように、継承していれば、親クラスのメソッドは使用できるのですが、逆に
継承していなければ他クラスのメソッドは使用できないとも言えます。

継承関係にはしたくないけれども、他クラスと全く同じメソッドを使いたい!と言う場合。
継承できないから同じ内容を毎回毎回クラスごとに書かなくてはいけないんでしょうか?
確かにそれでも良いかもしれませんが、コードの量が増えますし、
理想的なコーディングとして重複した処理は避けるべきです。

こんな時に役立つのがまさに!モジュールのミックスイン機能です!!
簡単に説明すると、共通のメソッドをモジュール内に定義しておき、
それをそれぞれのクラスで呼び出して使用することができる機能です。
このモジュールを呼び出すことをミックスインと呼びます。

#モジュールのミックスイン
ではさっそくモジュールのミックスインに関して解説します。
とりあえずモジュールの書き方に関して先に見ておいてください。以下のようになります!

test.rb
module モジュール名
 #モジュールの内容(メソッドやクラスなど)
end

書き方はいたって簡単ですね。ではさっそく使い方を解説します!
##include
まずはインスタンスメソッドをモジュール内に定義して継承関係ではない2つのクラスにそれぞれ適用するケースです。
module名Helloを最初に定義し、(#---①)
moduleを読み込むためにそれぞれのクラスでincludeします。
include モジュール名と書くだけで読み込むことができます。 (#---②)
Userクラス内のnameメソッド内でHelloモジュールのhelloメソッドを呼び出しています。(#---③)
同じくDogクラス内のnameメソッド内でもHelloモジュールのhelloメソッドを呼び出しています。(#---④)
その後、それぞれのクラスのインスタンスを作成し、nameメソッドを呼び出すと、ちゃんとnameメソッド内のhelloメソッドが呼び出されていることが確認できます。(#---⑤)

test.rb
module Hello   #---①
 def hello(name)
  puts "hello,#{name}"
 end
end

class User
 include Hello   #---②
 def name
  hello("たろう")  #---③
 end 
end

class Dog
 include Hello   #---②
 def name
  hello("ぽち")  #---④
 end 
end

user = User.new
user.name
# 出力結果 ==>"hello,たろう"   #--⑤

dog = Dog.new
dog.name
# 出力結果 ==>"hello,ぽち"   #---⑤

※モジュールもクラスも今回同じファイル内に書いてしまっていますが、もちろん別々にファイルを分けて頂いてOKです!
このように、モジュールで共通のメソッドをひとまとめにすることで、異なるクラスでもモジュール内のインスタンスメソッドが使用できます。

##extend
includeはインスタンスメソッドをモジュールから呼び出すために使用しましたが、クラスメソッドの呼び出しにはextendを使用します。
モジュールの定義方法はincludeの時と変わりません。

test.rb
module Hello
 def hello(name)
  puts "hello,#{name}"
 end
end

class User
 extend Hello 
 def self.name
  hello("たろう")
 end 
end

User.name
# 出力結果 ==>"hello,たろう"

つまり、モジュール内のメソッドをインスタンスメソッドとして使用するのか、クラスメソッドとして使用するのかでincludeとexcludeどちらを使うかが決まると言うことですね。
モジュール内の記述は変わらないので、同じモジュール内のメソッドでもクラスによってはインスタンスメソッドあるいはクラスメソッドになりうると言うことですね!とても便利です!

#さいごに
今回はモジュールの機能のうち、ミックスインに関して説明させて頂きました!
モジュールには他にも機能があるので、ぜひ気になる方は調べてみてください:relaxed:

【参考】
書籍 プロを目指すためのRuby入門(伊藤 淳一 著)

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?