Hello Ichihara.
Before
"I often use it in apps made with Rails ** I want to put my own methods in a separate file and use them where necessary **, but I don't know how to do it ..."
There was such a thing. I didn't understand ** class and module **, which seemed to be surprisingly known, so I summarized them in an article.
Roughly summarized, it looks like this.
Feature | how to use | Inheritance | instance | Superiority | |
---|---|---|---|---|---|
class | A collection of data and methods | Read the file with require, then inherit and use it as an instance method | 〇 | 〇 | Since multiple classes are grouped together using inheritance, it can be used like a framework. |
module | A collection of only methods and values | Read the file with reequire and then include,Used in extend | ✖ | ✖ | Collect data and use it where necessary, use it as a part |
class
class affects a wider range of objects through inheritance and instantiation.
python
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
#First read the file using require
require "calc/formulas"
#Inherit classes and inherit methods and data
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"
In the case of a class, first read the file using ** require **, let the class you want to use ** inherit **, and then ** create an instance **.
Therefore, it is suitable for ** inheriting a lot of data such as building MVC models and frameworks and linking each other **, but if you want to use it when you want to use data collectively, it will be described later. It can be said that ** module ** is more suitable.
module
Modules also have the role of grouping the same values and methods as class, but ** cannot create and inherit instances **.
Therefore, modules are easier to use than classes in terms of simply collecting information and calling it where it is needed.
There are two types ** to call module in class, ** include and extend **.
In a nutshell, include embeds module as ** instance method **, and extend embeds module as ** class method **.
In the following, ** math formulas are summarized as a module and called as an instance method. ** **
calc/formulas.rb
module Formula
#Three square theorem
def pythagorean_theorem(a, b)
p "c = #{Math::sqrt(a**2+ b**2)}"
end
#Solution formula
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
#Read
require "calc/formulas"
class Hoge
attr_accessor :name
#Use include in class
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"
In this way, the instance generated from the Hoge class can use pythagorean_theorem, which is the Pythagorean theorem, as a ** instance method **.
Then, when I read it in the same way with extend ...
python
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)
And you can see that the generated instance cannot use the method of module.
python
Hoge.pythagorean_theorem(3, 4)
#----------------------------------------------------------------
"c = 5.0"
You can use it by calling it as a ** class method **.
By the way, since the module is expanded in the class, you can use the instance method and class method in the class that inherits it **, respectively.
The following inherited the class using include.
python
class Fuga < Hoge
end
fuga = Fuga.new("fugafuga",20)
fuga.quadratic_formula(1, 3, 2)
#----------------------------------------------------------------
"x is -1.0 and -2.0"
If you want to use only ** methods directly without incorporating them into the class, you can use ** module method **.
python
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 +Define module method by method name
module_function :quadratic_formula
end
python
#Can be called in the same way as a class method
Formula.quadratic_formula(1, 8, 12)
#---------------------------------------------------
"x is -2.0 and -6.0"
As you can see, module is not necessary until ** class is created, but it can be used if you want to add a little function **.
It is preferable to use module if you just want to organize the data, and class if you want to embed the data in a part of the app using inheritance.