LoginSignup
1
1

More than 3 years have passed since last update.

【Ruby】実は理解できてないかも?【classとmoduleの違い】

Posted at

こんにちは市原です。

以前

「Railsで作ったアプリでよく使う自作メソッドを別ファイルにまとめて、必要ところで使いたいけど、やり方が分からぬ…」

といったことがありました。
意外と分かっているようでわかっていなかったclassとmodule、せっかくなので記事にまとめてみました。

calssとモジュール

ざっくりまとめるとこのようになります。

特徴 使用方法 継承 インスタンス 優位性
class データやメソッドをまとめたもの requireでファイルを読み込んでから継承しインスタンスメソッドとして使用 継承を使って複数のクラスをまとめるため、フレームワーク的な使い方ができる
module メソッドや値のみをまとめたもの reequireでファイルを読み込んでからinclude,extendで使用 データをまとめて必要個所で使用する、パーツとして使用

class

classは継承やインスタンスの生成を通じてより広い範囲のオブジェクトに影響を与えます。

class Formula
  def pythagorean_theorem(a, b)
    p "c = #{Math::sqrt(a**2+ b**2)}"
  end

  def self.quadratic_formula(a, b, c)
    x1 = (- b +Math::sqrt(b*b -4*a*c))/ 2 * a
    x2 = (- b -Math::sqrt(b*b -4*a*c))/ 2 * a
    p "x is #{x1} and #{x2}"
  end
end


calc/calculate.rb
# requireを使ってまずはファイルを読み込む
require "calc/formulas"

# クラスを継承してメソッドやデータを引き継ぎ
class Hoge < Formula

  attr_accessor :name

  def initialize(name, age)
    @name = name
    @age = age
  end

end

hoge = Hoge.new("hogehoge",22)
hoge.pythagorean_theorem(3, 4)

#-----------------------------------------------------------

"c = 5.0"

クラスの場合、まずはrequireを使ってファイルを読み込み、使いたいクラスに継承させ、その後インスタンスを生成するという流れになります。

そのためMVCモデルやフレームワークの構築といった、多くのデータを継承しそれぞれの連携を取る際は向いておりますが、ちょっとデータをまとめて使いたいときに使うという目的であれば後述するmoduleの方が適していると言えます。

module

モジュールもclassと同じ値やメソッドをまとめておける役割を持ちますが、インスタンスの生成と継承ができません

そのため単に情報をまとめておき、必要な場所で呼び出すといった面ではclassよりモジュールの方が使い勝手がいいです。

moduleをclass内で呼び出すにはincludeとextendの2種類があります。

includeとextend

一言で表すとincludeはインスタンスメソッドとしてmoduleを組み込み、extendはクラスメソッドとしてmoduleを組み込みます。

以下では数学の公式をmoduleとしてまとめ、インスタンスメソッドとして呼び出しています。

calc/formulas.rb
module Formula

 # 三平方の定理
  def pythagorean_theorem(a, b)
    p "c = #{Math::sqrt(a**2+ b**2)}"
  end


  # 解の公式
  def quadratic_formula(a, b, c)
    x1 = (- b +Math::sqrt(b*b -4*a*c))/ 2 * a
    x2 = (- b -Math::sqrt(b*b -4*a*c))/ 2 * a
    p "x is #{x1} and #{x2}"
  end

end

calc/calculate.rb
# 読み込み
require "calc/formulas"

class Hoge

  attr_accessor :name

  # クラス内でincludeを使用
  include Formula

  def initialize(name, age)
    @name = name
    @age = age
  end

end


hoge = Hoge.new("hogehoge",22)
hoge.pythagorean_theorem(3, 4)

#---------------------------------------------------

"c = 5.0"

このようにHogeクラスから生成されたインスタンスがピタゴラスの定理であるpythagorean_theoremをインスタンスメソッドとして使えるようになっています。

続いてextendで同様に読み込んでみると…

require "calc/formulas"

class Hoge
  attr_accessor :name

  extend Formula

  def initialize(name, age)
    @name = name
    @age = age
  end

  def hello
    p "Hello! I'm #{@name} "
    p "I'm #{@age} old"
  end

end

hoge = Hoge.new("hogehoge",22)
hoge.pythagorean_theorem(3, 4)

#--------------------------------------------------------------------

calculate.rb:26:in `<main>': undefined method `pythagorean_theorem' for #<Hoge:0x000000000504a3a8 @name="hogehoge", @age=22> (NoMethodError)

と、生成されたインスタンスはmoduleのメソッドを使うことはできないのが分かります。

Hoge.pythagorean_theorem(3, 4)

#----------------------------------------------------------------

"c = 5.0"

クラスメソッドとして呼び出してあげれば使えます。

ちなみにclass内でmoduleを展開するため、それを継承したクラスでもそれぞれインスタンスメソッド、クラスメソッドを使うことができますよ~

以下はincludeを使ってクラスを継承しました。


class Fuga < Hoge

end


fuga = Fuga.new("fugafuga",20)
fuga.quadratic_formula(1, 3, 2)

#----------------------------------------------------------------
"x is -1.0 and -2.0"

moduleメソッド

いちいちクラスに組み込まずに、ダイレクトでメソッドだけを使いたい場合moduleメソッドというものが使えます。

module Formula

  def pythagorean_theorem(a, b)
    p "c = #{Math::sqrt(a**2+ b**2)}"
  end

  def quadratic_formula(a, b, c)
    x1 = (- b +Math::sqrt(b*b -4*a*c))/ 2 * a
    x2 = (- b -Math::sqrt(b*b -4*a*c))/ 2 * a
    p "x is #{x1} and #{x2}"
  end

 # module_function + メソッド名でmoduleメソッドを定義
  module_function :quadratic_formula

end

#クラスメソッドと同じ要領で呼び出せる
Formula.quadratic_formula(1, 8, 12)

#---------------------------------------------------

"x is -2.0 and -6.0"

このようにmoduleはclassを作るまでは必要ないが、ちょっと機能を追加したい場合に使えます。

まとめ

データをまとめるだけならmodule、継承を使ってのアプリの一部にデータを組み込みたいならclassを使用するのが望ましいです。

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