LoginSignup
1
0

More than 1 year has passed since last update.

はじめに

これまで個人開発をしていて、Railsでmoduleを使うことはほとんど使うことはありませんでした。
実際にインターンをしてみると、moduleってかなり使われているなという印象です(特に名前空間としての役割)。
moduleがclassとどう違うのかや、どんな使われ方をするのかなどをまとめたいと思います。

moduleとclassの違いについて

moduleとclassの違いは以下の記事がとてもわかりやすいです。

  • moduleはインスタンスを生成できないが、classはできる
  • moduleは他のmoduleやclassを継承することはできないが、classは継承することができる

主な使い方

  • 名前空間として使う
  • メソッドを格納する場所として使う

名前空間としての使い方

特にこの使い方が多いのかなと思います。
moduleを使ってネストさせることによって名前空間を作ることができます。
小さなプロジェクトであれば名前の衝突をすることはほとんどありませんが、企業のリポジトリとなるとそうはいきません。
クラス名が同じだったとしても、それをラッピングするmoduleが異なれば衝突することはありません。

    module Rspec
        module Rails
            class ActiveRecordConfiguration
                # ...
            end
        end
    end

RSpec::Rails::ActiveRecordConfiguration
参照の際には::を使って表すことができます。

メソッド格納としての使い方

moduleではメソッドを格納することができます。
mixinして他のクラスで使うこともできますし、そのmodule単体のメソッドとして使うこともできます。

module単体で使いたいとき
mod.rb
    module Mod
        
        def return_hello
            'hello'
        end
    
        module_function :mod_only
    
    end

module_functionで指定することでmodule単体のメソッドとして定義されます。
=> Mod.return_helloで参照することができます。

mixinして使う場合
  • moduleをインスタンスメソッドとしてmixinしたいとき
    ↓ Post classでMod moduleをmixinすると想定します
mod.rb
    module Mod
    
        def return_hello
            'hello'
        end
    
        def return_self_instance
            return self
        end
    
        def return_self_attribute_title
            return self.title
        end
    
        def mod_only
            return 'only_module'
        end
    
        module_function :mod_only
    
    end

使いたいクラス内でincludeします。

post.rb
    class Post < ApplicationRecord
        include Mod
    end
    post = Post.first
    post.return_hello # => "hello"
    post.return_self_instance # => #<Post:0x000056107ac12fd8...
    post.return_self_attribute_title # => postインスタンスがtitle attributeを持っていた場合にはその値が返される(なければundefined method `title'が返される)
    post.mod_only # => no method errorが返される

どのクラスにincludeすることもできます。
attributeが一致しているならばself.attributeのようにmoduleでメソッドを定義しても、呼び出したクラスから使うことができます。
module_functionで指定しているものはmodule単体でしか使えないためinclude先で使うことはできません。
複数のクラスに共通する処理はmoduleに切り出すのがいいのかなと思います。

  • moduleをクラスメソッドとしてmixinしたいとき
    クラスメソッドとしてmixinしたい場合にはextendを使います。
    要領はインスタンスメソッドとしてmixinするときと全く同じです。
post.rb
    class Post < ApplicationRecord
        extend Mod
    end
    Post.return_hello # => 'hello'が返ってくる
    Post.return_self_instance # => selfを返すクラスメソッドであるためPost classが返ってくる
    # => Post(id: integer, title: string, content: string, user_id: integer, created_at: datetime, updated_at: datetime)
1
0
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
0