Ruby超入門 2周目 CHAPTER9 部品を共同利用する - モジュール まで

f:id:kkouji0224:20191105195214p:plain

 

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

こんばんは。昨日からやけに寒くなってきましたね。夜中に目が覚めてガクブルでした。koujiです。

 

さーて今日からCHAPTER9を振り返っていきまーす!モジュールさんですね。

 

モジュールさん

 module Topping
    def menma
        @name += "トッピングでメンマ"
    end
    def chashu
        @name += "トッピングでチャーシュー"
    end
    def egg
        @name += "トッピングでタマゴ"
    end
    def wakame
        @name += "トッピングでわかめ"
    end
end

class SoySourceRamen
    include Topping
    def initialize
        @name = "醤油ラーメン"
    end
    def name
        @name
    end
end

class SaltRamen
    include Topping
    def initialize
        @name = "塩ラーメン"
    end
    def name
        @name
    end
end

class MisoRamen
    include Topping
    def initialize
        @name = "味噌ラーメン"
    end
    def name
        @name
    end
end

saltramen = SaltRamen.new
saltramen.chashu
puts saltramen.name

 

まずはモジュールってなんじゃらほいって感じだよね。クラスと似てるんだけど、クラスと違ってインスタンスを作ることができないんだ。メソッドを共同利用するためのものって感じかな。

 

まず書き方は見ての通りなんだけど。module 先頭大文字のモジュール名 endって感じで書くよ。中にメソッドを書く感じだね。上の場合だと@nameにチャーシューとかワカメとかタマゴを追加するってやつだね。

 

で、モジュールのメソッドをクラスで使うにはinclude モジュール名。これをクラスの中に書いておくとモジュールで定義したメソッドが実行できるようになるんだね。ちなみにincludeは入れるとか組み込むとか含むとかそんな意味らしい。そのまんまだね!!

 

で、モジュールは複数のクラスで共同利用ができるんだね。上を見てもらえばわかると思うんだけど、醤油らーめんクラスでも塩らーめんクラスでも味噌らーめんクラスでもincludeしてるんだぜっ!!これはめっちゃ便利だしわかりやすいねー。

 

こんな感じでモジュールを使うとクラス継承とは違った感じでメソッドが共同利用できるんだね。今回のらーめんプログラムはもしかしたら継承で作ったほうが違和感ないかもしれないけど、他に思いつかなかったってことで!継承でやるかモジュールでやるかは今後慣れていこうかなって感じ。

 

モジュールにクラスメソッド定義

 

module Topping
    def self.info
        "ラーメンのトッピン具材だよ"
    end

 

こんな感じでクラスの時と同じだね。.selfだね。こうやって書いてあげるとputs Topping.infoで呼び出せるよ!

 

モジュールで定数をつかう

 

module Topping
    Price = "150円"
    def self.info
        "ラーメンのトッピン具材だよ! 全部" + Price
    end

 

こんな感じで使えるね。定数は先頭が大文字ね。

 

定数を使う時はこんな感じで呼び出す。

 

puts Topping::Price

 

Topping::Priceって書いてあるようにモジュール名::定数名だね。

 

Rubyが用意しているモジュール

 

puts Math::PI
puts Math::cos(Math::PI)

 

上のはRubyが用意してくれているMathモジュールで数学計算用クラスメソッドとか定数が定義されてるみたい。リファレンスのモジュールのところに他のモジュールも書いてあるんだけどちょっと難しそうなので今回は触れずにおこう…。

 

名前空間

 

module SaltRamen
    class Ramen
        def self.info
            "自慢の塩ラーメン"
        end
    end
end
module MisoRamen
    class Ramen
        def self.info
            "自慢の味噌ラーメン"
        end
    end
end

puts SaltRamen::Ramen.info
puts MisoRamen::Ramen.info

 

同じクラス名を複数使いたいけど、別々のクラスとして定義して分けたいときはこんな感じで書いてあげるといいみたい。これを名前空間を作るって言うんだってよ!!

 

上見てもらうとわかると思うんだけど、SaltRamen::RamenとかMisoRamen::Ramenみたいな感じで使い分けができるようになるね。

 

インスタンスを作るときはクラス、作らない時はモジュールを使うと意図が伝わりやすいようだ。名前空間をわけるだけならモジュールでいいね!

 

別ファイルのクラスとかモジュールを読み込む

 

ramenmodule.rb

module Topping
    Price = "150円"
    def self.info
        "ラーメンのトッピン具材だよ! 全部" + Price
    end
    def menma
        @name += "トッピングでメンマ"
    end
    def chashu
        @name += "トッピングでチャーシュー"
    end
    def egg
        @name += "トッピングでタマゴ"
    end
    def wakame
        @name += "トッピングでわかめ"
    end
end

 

ramen.rb

require_relative "ramenmodule"
class SoySourceRamen
    include Topping
    def initialize
        @name = "醤油ラーメン"
    end
    def name
        @name
    end
end

class SaltRamen
    include Topping
    def initialize
        @name = "塩ラーメン"
    end
    def name
        @name
    end
end

class MisoRamen
    include Topping
    def initialize
        @name = "味噌ラーメン"
    end
    def namerequire_relative
        @name
    end
end

saltramen = SaltRamen.new
saltramen.chashu
puts Topping.info
puts Topping::Price
puts saltramen.name

 

さっき書いた1つのファイルをmoduleとclassで分割してみたよ。で、classの方にrequire_relativeメソッドを書いてramenmodule.rbを読み込んでToppingモジュールを使ってる感じだね。読み込む側でrequire_relativeの引数が文字列でファイル名だね。.rbは省略可だよ。例えば、これから新しいプログラムを書いて、そこからrequire_relativeで読み込むこともできちゃうわけだねぇ〜!!便利っす!

 

ちなみにrequire_relativeメソッドじゃなくてrequireメソッドを使うことも出来るんだけど、その場合はrequire "./ファイル名"と書けるみたいなんだけど、別ファイルを読み込むときはrequire_relativeがオススメらしいっす!

 

includeとrequire_relativeは似てる感じするけど…

 

include

モジュール名を渡してそのモジュールに書かれたメソッドをクラスから使えるようにするメソッド!

 

require_relative

ファイル名を渡して、そのファイルに書かれたクラスやモジュールを使えるようにするメソッドだよ!

 

って感じでちょっと駆け足気味に振り返ってみました!インスタンスを作る時と作らないときで使い分けていけばいいんだなぁー。ってのはわかったんだけど、実際にどんな場面で使い分けるのかなぁって感じなので、その辺は今後嫌でもわかってくるだろうから特にきにしないでおこう!!

 

それにしても「なるほどなぁー」って感じで面白い。

 

昨日Twitterでふと思ったんだけど「勉強」でもないし完全に「遊んでる」って感じでもないんだけど、その中間にあるような言葉ってなんだろうね?

 

そんなことを考えながら楽しんでまっす!!

 

ってことで今日はこの辺で。アディオス!!