私の質問は「 Rubyでのincludeとextendの違いは何ですか? 」と似ています。
Rubyのrequire
とinclude
の違いは何ですか?自分のクラスのモジュールのメソッドを使いたいだけなら、それをrequire
にするのかinclude
にするのか?
Rubyの "include"と "require"の違いは何ですか?
答え:
Includeメソッドとrequireメソッドは、まったく異なることをします。
Requireメソッドは、他のほとんどのプログラミング言語で行われていることと同じことを行います。別のファイルを実行します。また、過去に何が必要だったかを追跡し、同じファイルを2回必要とすることはありません。この機能を追加せずに別のファイルを実行するには、loadメソッドを使用できます。
Includeメソッドは他のモジュールからすべてのメソッドを受け取り、それらを現在のモジュールに含めます。 requireのようなファイルレベルのものとは対照的に、これは言語レベルのものです。 includeメソッドは、クラスを他のモジュールで拡張するための主な方法です(通常はミックスインと呼ばれます)。たとえば、クラスでメソッド "each"を定義している場合は、mixinモジュールEnumerableを含めることができ、それをコレクションとして機能させることができます。他の言語ではインクルード動詞の使い方が非常に異なるため、これは混乱を招く可能性があります。
ですから、モジュールを拡張したりミックスインしたりするのではなく、単にモジュールを使用したい場合は、require
を使用します。
おかしなことに、Rubyのrequire
はCのinclude
に似ていますが、Rubyのinclude
はCのinclude
とほとんど同じです。
メタプログラミングRubyの本から、
require()
メソッドはload()
と非常によく似ていますが、異なる目的のためのものです。コードを実行するにはload()
を使用し、ライブラリをインポートするにはrequire()
を使用します。
あなたがモジュールを使っているなら、それはあなたがあなたのクラスにすべてのメソッドを持ってきていることを意味します。あなたがモジュールを持つクラスを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'
Rubyのrequire
は他の言語(Cなど)では "include"に似ています。これはRubyに別のファイルの内容を取り込むにしたいことを伝えます。他の言語における同様のメカニズムは次のとおりです。
Rubyのinclude
はミックスインに使われるオブジェクト指向の継承機構です。
ここには良い説明があります:
単純な答えは、requireとincludeは本質的に無関係だということです。
"require"はCのインクルードに似ています。 (1つの注目すべき違いは、必須ファイルが完了すると、必須ファイル内のローカルユーザーが「蒸発」することです。)
RubyのincludeはCのインクルードのようなものではありません。 includeステートメントはモジュールをクラスに「混ぜ込む」。これは限定された形式の多重継承です。インクルードされたモジュールは文字通りそれを含むものに対して "is-a"関係を授けます。
強調を加えた。
Programming Ruby 1.9から
先に進む前に、includeステートメントについていくつか指摘しておきます。まず、ファイルとは関係ありません。 Cプログラマーは、コンパイル中にあるファイルの内容を別のファイルに挿入するために#includeというプリプロセッサ指令を使用します。 Rubyのinclude文は単にモジュールへの参照を作成します。そのモジュールが別のファイルにある場合は、includeを使用する前にrequire(またはあまり使用されていない従兄弟であるload)を使用してそのファイルをドラッグする必要があります。次に、Rubyのインクルードは、モジュールのインスタンスメソッドを単純にクラスにコピーするのではありません。代わりに、クラスからインクルードモジュールへの参照を作成します。そのモジュールが複数のクラスに含まれる場合、それらはすべて同じものを指します。プログラムの実行中であっても、モジュール内のメソッドの定義を変更すると、そのモジュールを含むすべてのクラスで新しい動作が見られます。
あなたは今までにモジュールをrequire
しようとしましたか?結果はどうでしたか?ちょうど試して:
MyModule = Module.new
require MyModule # see what happens
モジュールは必須ではなく、含まれているだけです。
以下に示すように、モジュールをクラスに含めると、モジュール内で定義されたコードを取得してクラス内に挿入したように、それを「含める」ことができます。それは「ミックスイン」動作を可能にします。たとえば、モジュール内に同じコードを必要とするクラスが複数ある場合など、重複を避けるためにコードをDRYするために使用されていました。
ロードロードメソッドは、そのライブラリがロードされているかどうかを追跡しないことを除けば、requireメソッドとほとんど同じです。そのため、ライブラリを複数回読み込むことができます。また、loadメソッドを使用するときは、ライブラリファイル名の拡張子「.rb」を指定する必要があります。
Requireメソッドを使用すると、ライブラリをロードして、複数回ロードされるのを防ぐことができます。初回以降に同じライブラリをロードしようとすると、requireメソッドはfalseを返します。 requireメソッドは、ロードしているライブラリが別のファイルで定義されている場合にのみ使用する必要があります。これは通常そうです。
あなたはこれを好むことができます http://ionrails.com/2009/09/19/Ruby_require-vs-load-vs-include-vs-extend/
require(name)
真偽値true/falseを返します
Requireにパラメータとして渡される名前は、Rubyはあなたのロードパスでその名前のソースファイルを見つけようとします。初回以降に同じライブラリをロードしようとすると、requireメソッドはfalseを返します。 requireメソッドは、ロードしているライブラリが別のファイルで定義されている場合にのみ使用する必要があります。そのため、そのライブラリがすでにロードされているかどうかを追跡します。
include module_name
2つの異なるクラスで必要なメソッドがいくつかあるとします。それなら、両方のクラスでそれらを書く必要はありません。代わりにあなたができることはモジュールでそれを定義することです。そしてこのモジュールを他のクラスに含めます。 DRYの原則を保証するためだけにRubyから提供されています。重複を避けるため、コードをDRYアップするために使用されていました
以下はrequireとincludeの基本的な違いのいくつかです。
必須:
含める:
含める
モジュールを自分のクラスに
include
すると、そのモジュール内で定義されているコードを取得してクラス内に挿入したのと同じようになります。それは「ミックスイン」動作を可能にします。たとえば、モジュール内に同じコードを必要とするクラスが複数ある場合など、重複を避けるためにコードをDRYするために使用されていました。
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
この質問に答える前に、PHPでなぜinclude()とrequire()を使用するのかについて簡単に説明します。
サーバーが実行する前に、1つのPHPファイルの内容を別のPHPファイルに挿入する。 include()
とrequire()
に関するもう少し詳細。
include() - 指定したファイルを含みます。ファイルが見つからず、残りのスクリプトが実行されなかった場合は、警告が表示されます。ファイルが不要な場合はinclude()を使用し、ファイルが見つからない場合はアプリケーションフローを続行します。
構文 -
「filename」を含めます。
include()
を使う代わりに、include_once()
を使うことができます。
include_once() - 指定されたファイルも含みますが、ファイルが既に含まれている場合は、再び含まれることはありません。ファイルを見つけられずに残りのスクリプトを実行できなかった場合も警告を出します。
構文 -
include_once();
require() - 指定されたファイルも含みますが、ファイルの検索に失敗して実行を停止すると致命的なエラー(E_COMPILE_ERROR)をスローします。
構文
「ファイル名」が必要です。
require()
を使う代わりにrequire_once();
を使うことができます
require_once() - 指定されたファイルも含みますが、ファイルが既に含まれている場合は、再び含まれることはありません。ファイルの検索に失敗して実行を停止すると、致命的エラー(E_COMPILE_ERROR
)がスローされます。
構文
require_once();