web-k.log

RubyやWebをメインに技術情報をのせていきます

Rubyのrequire/load/autoload/include/extendについて

| Comments

require/load/autoload/include/extend の違いについて

まず、ファイルをロードする require/load/autoload と ロードしない include/extend に分けられる。 違いについては、次で個別に説明した後に表にしてまとめる。

require

  • Kernelモジュールのメソッド
  • 同じファイルは複数回ロードされない
  • Rubyライブラリをロードする
    • RubyライブラリはRubyスクリプト(*.rb)と拡張ライブラリ(*.so,*.o,*.dllなど)を指す
  • ロードするファイルパスは、絶対パスでも相対パスでも可
  • ロードするファイル名の拡張子は自動補完してくれるため、省略可(*.rb 優先)
1
require 'ファイル名'

load

  • Kernelモジュールのメソッド
  • 同じファイルを再ロードできる
  • ロードするファイルパスは、絶対パスでも相対パスでも可
  • ロードするファイル名の拡張子は省略できない
  • 拡張ライブラリは読み込み対象ではない(できないかは不明)
  • .txtのようなファイルでもロードできる
1
load 'ファイル名'

autoload

  • Kernelモジュール(トップレベル)、Moduleクラス の2種類のメソッドがある
  • autoloadと書いた段階では、ファイルはロードされない
    • 定数const_nameを参照したときに、はじめて第2引数であるファイルが require される
    • 定数const_nameには”::”演算子が使えないため、ネストする場合は2種類のメソッドを組み合わせて使用する
  • いずれ廃止されそうなメソッド
1
autoload(const_name, 'ファイル名')

include

  • Moduleクラスのメソッド
    • Moduleクラスはクラスとモジュールを表し、ClassクラスはModuleのサブクラスになる
  • クラスやモジュールに他のモジュールをインクルード(Mix-in)する
    • 引数に指定できるのはモジュールのみ
    • 引数に複数のモジュール指定可
  • includeしたクラスのインスタンスメソッドとして使用可能
1
include(module, ...)

extend

  • Objectクラスのメソッド
  • オブジェクトの特異クラスに引数に指定したモジュールを取り込み、モジュールのメソッドを特異メソッドとして使えるようにする
    • 特異メソッドは特定のインスタンス固有のメソッドのこと
      • クラスを作った後にメソッドを追加すると特異メソッドになる
    • 特異クラスは特定のインスタンスのために用意されるクラスのこと
      • 特異クラスは特異メソッドをまとめて定義するときなどに使用される
  • extendしたクラスのクラスメソッドとして使用可能(インスタンスメソッドではない)
1
extend(module, ...)

extendは使用したことがなかったので、具体例を以下に示す。

extendの具体例
1
2
3
4
5
6
7
8
9
module Test
  def test
    puts self + "Test"
  end
end
str = "Hoge"
str.extend(Test)
str.test
>> HogeTest

require/load/autoload の違い

  require load autoload
メソッドの定義元 Kernelモジュール Kernelモジュール Kernelモジュール or Moduleクラス
複数回ロード されない される されない(requireに従うので以下省略)
ロード時の拡張子省略 不可
ロード可能ライブラリ Rubyスクリプト+拡張ライブラリ Rubyスクリプト

requireはライブラリのロードをしたいとき、loadは設定ファイルなど再読み込み可能にしたいとき、というように使い分けられる。 また、拡張子が.rbや.soなどではない.txt(中身はruby)ファイルをロードしたいときにも load を使用する。

include/extend の違い

  include extend
メソッドの定義元 Moduleクラス Objectクラス
振る舞い includeしたクラスのインスタンスメソッドとして使用 extendしたクラスのクラスメソッドとして使用

振る舞いの違いがわかりにくいので、以下に例を示す。

include/extendの例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module Hoge
  def test
    puts "HogeTest"
  end
end

class IncludeTest
  include Hoge
end
class ExtendTest
  extend Hoge
end

IncludeTest.new.test #インスタンスメソッド
>> HogeTest
ExtendTest.test #クラスメソッド
>> HogeTest

参考

Comments