Rubyでは、共通する処理をまとめるためにモジュール(Module)を利用します。その際によく使われるのがincludeとextendですが、どちらもモジュールを利用するための機能であるため、違いが分かりにくいと感じる人も少なくありません。この記事では、Rubyのincludeとextendの違いや使い分け、具体的なコード例を交えながら解説します。
Rubyのモジュールとは何か
Rubyのモジュールとは、メソッドや定数などをまとめて管理するための仕組みです。クラスと似ていますが、モジュールはインスタンスを作成することができません。
主な用途は、複数のクラスで共通して利用したい処理をまとめることです。これにより、同じコードを何度も書く必要がなくなり、保守性の高いプログラムを作成できます。
例えば、複数のクラスでログ出力機能や認証機能などを共有したい場合、モジュールに処理を定義して各クラスから利用する方法がよく使われます。
includeはインスタンスメソッドとしてモジュールを追加する
includeは、モジュールのメソッドをクラスのインスタンスメソッドとして追加するために使用します。
例えば、以下のようなモジュールを作成します。
<pre><code>module Greeting
def hello
puts “こんにちは”
end
end
class User
include Greeting
end
user = User.new
user.hello
</code></pre>
この場合、GreetingモジュールのhelloメソッドはUserクラスのインスタンスメソッドになります。そのため、Userクラスのインスタンスから呼び出すことができます。
つまりincludeは「このクラスのオブジェクトが使える機能を追加する」というイメージです。
extendはクラスメソッドとしてモジュールを追加する
extendは、モジュールのメソッドをクラスメソッドとして追加するときに使用します。
先ほどと同じモジュールをextendで利用すると動きが変わります。
<pre><code>module Greeting
def hello
puts “こんにちは”
end
end
class User
extend Greeting
end
User.hello
</code></pre>
この場合、helloメソッドはUserクラス自体に追加されます。そのため、User.newのように作成したインスタンスではなく、User.helloという形で呼び出します。
つまりextendは「クラスそのものに機能を追加する」というイメージになります。
includeとextendの違いを比較
includeとextendの大きな違いは、モジュールのメソッドがどこへ追加されるかです。
| 機能 | 追加される場所 | 呼び出し方 |
|---|---|---|
| include | インスタンスメソッド | オブジェクト.メソッド |
| extend | クラスメソッド | クラス名.メソッド |
例えば、Userというクラスに「ユーザーごとに実行する処理」を追加したい場合はincludeを使います。一方で「Userクラス全体に関する処理」を追加したい場合はextendが適しています。
具体例として、ユーザーがログインする処理やプロフィールを表示する処理はinclude向きです。一方で、全ユーザーを検索する処理や設定情報を取得する処理などはextendで追加するケースがあります。
extend selfを使うとモジュール自身から呼び出せる
Rubyではextend selfという書き方もよく利用されます。これは、モジュール内のメソッドをモジュール自身のクラスメソッドとして利用できるようにする機能です。
<pre><code>module Calculator
extend self
def add(a, b)
a + b
end
end
puts Calculator.add(1, 2)
</code></pre>
このように書くことで、Calculator.newのようなインスタンス化をせずにCalculator.addのように呼び出せます。便利な処理をまとめたユーティリティモジュールなどでよく利用されます。
Rubyでincludeとextendを使い分けるポイント
includeとextendを使い分けるときは、「その機能を誰が利用するのか」を考えると分かりやすくなります。
インスタンスごとに利用したい機能ならinclude、クラス全体で利用したい機能ならextendを選択します。
例えば、車のクラスで考えると、車ごとに走る機能を追加するならinclude、車種一覧を取得するようなクラス全体の機能を追加するならextendを使うという考え方になります。
まとめ|includeはインスタンス向け、extendはクラス向け
Rubyのincludeとextendは、どちらもモジュールを再利用するための仕組みですが、追加される場所が異なります。
includeはモジュールのメソッドをインスタンスメソッドとして追加し、extendはクラスメソッドとして追加します。
「作成したオブジェクトが使う機能なのか」「クラス自体が使う機能なのか」を基準に考えることで、includeとextendを適切に使い分けられるようになります。


コメント