Rubyのincludeとrequireの違いは何ですか?


465

私の質問は「Rubyでのincludeとextendの違いは何ですか?」に似ています

違いは何だrequireincludeRubyでは?クラスのモジュールのメソッドを使用したいだけの場合、それを使用するrequire必要がincludeありますか、それともそれを使用する必要がありますか?


1
価値のあるものについては、requireinclude、および関連するのコミュニティドキュメントへのリンクを次に示しますModule#append_features

回答:


543

Rubyの「include」と「require」の違いは何ですか?

回答:

includeメソッドとrequireメソッドは非常に異なる処理を行います。

requireメソッドは、他のほとんどのプログラミング言語でincludeが行うことを実行します。別のファイルを実行します。また、過去に必要なものを追跡し、同じファイルを2回必要としないようにします。この追加機能なしで別のファイルを実行するには、loadメソッドを使用できます。

includeメソッドは、すべてのメソッドを別のモジュールから取得し、現在のモジュールに含めます。これは、requireの場合のようにファイルレベルのものとは対照的に、言語レベルのものです。includeメソッドは、他のモジュール(通常はミックスインと呼ばれます)でクラスを「拡張」するための主要な方法です。たとえば、クラスがメソッド「each」を定義している場合は、mixinモジュールEnumerableを含めることができ、コレクションとして機能できます。他の言語ではinclude動詞の使い方が非常に異なるため、これは混乱を招く可能性があります。

ソース

したがって、モジュールを拡張したり、ミックスインしたりするのではなく、単にモジュールを使用したい場合は、を使用する必要がありますrequire

奇妙なことに、RubyのはrequireCさんに似ているincludeRubyのは、一方で、includeほとんどのCのようなものではありませんinclude


45
実際、Cのincludeは、requireのようにファイルをロードしませんが、#include行をファイルのコンテンツに置き換えます。インクルードされるファイルは「ヘッダー」である必要はなく、#includeはファイルの先頭にある必要はありませんが、クラスやメソッド定義など、どこにでも置くことができます。これは、ファイルにいくつかのメソッドを記述してクラスのコードに含めることで、C ++でmixinを実行できることを意味します。したがって、実際にはCでは一般的ではありませんが、それほど遠くはありません。
mb14

13
この答えは、例を含めることでメリットがあります。
Travis Bear、

12
mb14のコメントはこれを意味しますが、明示的に述べる必要があります。答えが言うこととは逆に、requireはファイルを「実行」するのではなく、包含ファイルの一部であるかのようにロードします。これはセマンティックな問題のように見えるかもしれませんが、実際にはかなり重要な違いです。
Lonny Eachus 14

素晴らしい説明。「奇妙なことに、RubyのrequireはCのincludeに類似していますが、RubyのincludeはCのincludeとほとんど同じではありません。」
ArtSabintsev 2014

1
@GregSchmit:includeRubyでの継承は単純です。class C; include M end作るMのスーパークラスCとの(旧)スーパークラスCのスーパークラスをM。Cはinclude継承を介して機能するとは思わない。単純なテキスト/字句の置き換えだと思う。
イェルクWミッターク

100

モジュールを使用している場合は、すべてのメソッドをクラスに組み込むことになります。extendモジュールを含むクラスの場合、それは、モジュールのメソッドをクラスメソッドとして「組み込む」ことを意味します。includeモジュールを含むクラスの場合は、モジュールのメソッドをインスタンスメソッドとして「取り入れ」ていることになります。

例:

 module A
   def say
     puts "this is module A"
   end
 end

 class B
   include A
 end

 class C
   extend A
 end

B.say => B:Classの未定義メソッド 'say'

B.new.say =>これはモジュールAです

C.say =>これはモジュールAです

C.new.say => C:Classの未定義のメソッド 'say'


23
これは質問には答えないと思いますが、私が探していたものです=)
Ciro Santilli郝海东冠状病六四事件法轮機能

2
これは実際にrequireとの違いについての質問には答えませんinclude

94

メタプログラミングRubyの本から、

このrequire()方法はと非常に似てload()いますが、別の目的のために用意されています。を使用load()してコードを実行し、 require()ライブラリをインポートします。


73
回答で他の言語と比較しないことに対する賛成:)
Stevo

質問のコンテキストで答えを提供しないことに対する反対票:「クラスのモジュールのメソッドを使用したいだけなのですか?」
2016年

57
  • Ruby requireは他の言語(Cなど)の「include」に似ています。Ruby に別のファイルの内容取り込みたいことを伝えます。他の言語での同様のメカニズムは次のとおりです。

  • Ruby includeは、ミックスインで使用されるオブジェクト指向の継承メカニズムです。

ここに良い説明があります

[]簡単な答えは、requireとincludeは本質的に無関係であることです。

"require"はCのincludeに似ており、初心者の混乱を引き起こす可能性があります。(1つの顕著な違いは、requireが完了すると、requiredファイル内のローカルが「蒸発」することです。)

Ruby インクルードは、Cインクルードとは異なります。includeステートメントは、モジュールをクラスに「ミックスイン」します。これは多重継承の限定的な形式です。インクルードされたモジュールは、それを含むものに文字通り「is-a」関係を与えます。

強調が追加されました。


7

requireモジュールを試したことがありますか?結果はどうでしたか?ちょうど試して:

MyModule = Module.new
require MyModule # see what happens

モジュールは必須ではなく、含まれているだけです!


ここのアサーションは正しくありません。モジュールが必要になる場合があります。そして、上記のコードを実行している誰もがTypeError、単語Moduleがに変更された場合、同じ結果()を受け取ることがわかりますClass
pjd

7

プログラミングRuby 1.9から

先に進む前に、includeステートメントについていくつかのポイントを説明します。まず、ファイルとは何の関係もありません。Cプログラマは、#includeと呼ばれるプリプロセッサディレクティブを使用して、コンパイル時に1つのファイルの内容を別のファイルに挿入します。Rubyのincludeステートメントは、単にモジュールへの参照を作成します。そのモジュールが別のファイルにある場合は、includeを使用する前に、require(またはあまり一般的に使用されていないいとこ、load)を使用してそのファイルをドラッグする必要があります。第2に、Rubyインクルードはモジュールのインスタンスメソッドをクラスに単にコピーするだけではありません。代わりに、クラスから含まれているモジュールへの参照を作成します。複数のクラスがそのモジュールを含む場合、それらはすべて同じものを指します。プログラムの実行中でも、モジュール内のメソッドの定義を変更すると、


3

インクルード以下に示すように、モジュールをクラスにインクルードすると、モジュール内で定義されたコードを取得してクラスに挿入したときのように、インクルードします。'mixin'動作を許可します。たとえば、モジュール内に同じコードを必要とするクラスが複数ある場合など、重複を避けるためにコードを乾燥させるために使用されます。

Load loadメソッドは、そのライブラリが読み込まれたかどうかを追跡しないことを除いて、requireメソッドとほとんど同じです。したがって、ライブラリを複数回ロードすることが可能であり、loadメソッドを使用する場合は、ライブラリファイル名の「.rb」拡張子を指定する必要があります。

Require requireメソッドを使用すると、ライブラリをロードして、2回以上ロードされるのを防ぐことができます。初めて同じライブラリをロードしようとすると、requireメソッドは「false」を返します。ロードするライブラリが別のファイルで定義されている場合にのみrequireメソッドを使用する必要があります。これは通常のケースです。

あなたはこれを好むことができます http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/


3

requireとincludeの基本的な違いは次のとおりです。

必要とする:

  1. Requireは、ファイルシステムからファイルを読み取り、解析してメモリに保存し、所定の場所で実行します。つまり、スクリプトの実行中に何かを変更しても、その変更は反映されません。
  2. モジュール名ではなく名前でファイルが必要です。
  3. 通常、ライブラリと拡張機能に使用されます。

含める:

  1. モジュールをクラスに含めると、モジュールで定義されたコードを取得してクラスに挿入したかのように動作します。
  2. ファイル名ではなく、モジュール名を含めます。
  3. これは通常、コードを空にし、コードの重複を取り除くために使用されます。

2
require(name)

ブール値のtrue / falseを返します

requireにパラメーターとして渡される名前。rubyは、ロードパスでその名前のソースファイルを見つけようとします。初めて同じライブラリをロードしようとすると、requireメソッドは「false」を返します。ロードするライブラリが別のファイルで定義されている場合のみ、requireメソッドを使用する必要があります。そのため、そのライブラリがすでにロードされているかどうかを追跡します。

include module_name

2つの異なるクラスに必要なメソッドがいくつかあるとします。その後、両方のクラスでそれらを記述する必要はありません。代わりに、モジュールでそれを定義できます。そして、このモジュールを他のクラスに含めます。Rubyは、DRYの原則を確実にするために提供しています。重複を避けるためにコードを乾燥させるために使用されます


2

含める

includeモジュールをクラスに入れると、モジュール内で定義されたコードを取得して、それをクラス内に挿入したときのように、「インクルード」します。'mixin'動作を許可します。たとえば、モジュール内に同じコードを必要とするクラスが複数ある場合など、重複を避けるためにコードを乾燥させるために使用されます。

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  include Log 
  # ... 
end

tc = TestClass.new.class_type # -> success
tc = TestClass.class_type # -> error

必要とする

requireメソッドを使用すると、ライブラリをロードして、ライブラリが複数回ロードされるのを防ぐことができます。初めて同じライブラリをロードしようとすると、requireメソッドは「false」を返します。ロードするライブラリが別のファイルで定義されている場合にのみrequireメソッドを使用する必要があります。これは通常のケースです。

そのため、そのライブラリがすでにロードされているかどうかを追跡します。また、ライブラリファイル名の拡張子「.rb」を指定する必要もありません。requireの使用例を以下に示します。requireメソッドを「.rb」ファイルの最上部に配置します。

負荷

loadメソッドは、ライブラリが読み込まれたかどうかを追跡しないことを除いて、requireメソッドとほとんど同じです。したがって、ライブラリを複数回ロードすることが可能であり、loadメソッドを使用する場合は、ライブラリファイル名の「.rb」拡張子を指定する必要があります。

伸ばす

includeメソッドの代わりにextendメソッドを使用する場合、モジュールのメソッドをインスタンスメソッドではなくクラスメソッドとして追加します。

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type

2

「ロード」-ファイルの内容を挿入します(ファイルが呼び出されるたびにファイルを解析します)。

「必須」-ファイルを解析したコンテンツを挿入します(ファイルは一度解析され、メモリに保存されます)

「含む」-モジュールをクラスに組み込み、モジュール内のメソッドをクラスのインスタンスメソッドとして使用できます。

「拡張」-モジュールをクラスに組み込み、モジュール内のメソッドをクラスメソッドとして使用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.