モジュールとクラスを使用する場所を教えてください。Ruby のモジュールの使いやすさと適用性の原則とは何ですか?
6 に答える
モジュールは、メソッドと定数のコレクションです。インスタンスを生成できません。クラスはインスタンス (オブジェクト) を生成し、インスタンスごとの状態 (インスタンス変数) を持つことができます。モジュールは、クラスや他のモジュールに混在させることができます。混合されたモジュールの定数とメソッドは、そのクラスのものに溶け込み、クラスの機能を拡張します。ただし、クラスを何にも混在させることはできません。クラスは別のクラスから継承できますが、モジュールからは継承できません。モジュールは何からも継承できません。-- Ruby FAQ
クラスは重要なものだけを含む信頼できる抽象化であり、モジュールは情報やサービスを提供できるコンテナーであり、さらに特異性を保つ場所にもなります。たとえば、内気な人を分類し、臆病者をこの分類の特異点にすることができます。ShyPeople はクラスであり、Timidity は ShyPeople クラスに含まれるモジュールです。
「何が問題なの?」,「それはモジュールのメソッドですか、それともクラスのメソッドですか?」または「それはクラスまたはモジュールになりますか?」経験だけの質問であり、RL のアナロジーが役に立ちます。詳細については、読んでコーディングすることをお勧めします:)
クラスはモジュールです。違いは、クラスをインスタンス化できることです。
両方の使用法は、クラス/モジュールがどのように使用されるか、それが何を表すかに本当に依存しています...
この質問に対する究極の答えはありません。いずれにせよ(私見)、それはコードを読んだり書いたり、イディオムやデザインパターンについて学んだりすることで学ぶものです...
私の簡単な経験則は、インスタンス変数の作成など、オブジェクトの内部状態を保持する必要がある場合は、クラスを使用するということです。
他のすべてにはモジュールを使用します。これには、名前空間、ミックスイン、およびユーティリティ オブジェクトが含まれます。
基本的に、Ruby モジュールはクラスに似ていますが、オブジェクトのファクトリ部分はありません。通常、Ruby 開発者はモジュールを使用して、複数のクラスで使用する必要があるメソッドのグループを格納します。これは、とりわけ、非常に反ルビストなパターンであるサブクラスの使用を避けるための優れた方法です。
いずれにせよ、それはほとんど哲学的な質問であり、短い方法で適切に答えることはできません. Ruby の基本に関する本 (Eloquent Ruby など) を読んでみてください。
モジュールは名前空間および mixin として使用されます。Ruby は多重継承をサポートしていません。ただし、クラスが他の複数のクラス内で定義されたメソッドを取得することでメリットが得られる場合があります。これは、モジュールと呼ばれる構造を使用することで可能になります。モジュールは、継承もインスタンス化もサポートしないことを除けば、クラスに似ています。主に、複数のメソッドを格納するためのコンテナーとして使用されます。モジュールを使用する 1 つの方法は、クラス内で include または extend ステートメントを使用することです。このようにして、クラスはモジュール内で定義されたすべてのメソッドとオブジェクトにアクセスできます。クラスにモジュールが混在しているとのこと。したがって、ミックスインはクラスに含まれる単なるモジュールです。1 つのモジュールを複数のクラスに混在させることができ、1 つのクラスに複数のモジュールを混在させることができます。したがって、Ruby によって課される制限はすべて
すべてのモジュールは Module クラスのインスタンスです。
module Foo
end
Foo.instance_of? Module # Output: => true
次の例では、JapaneseGreetings モジュールが (ミックスインとして) Person クラスに含まれています。
module JapaneseGreetings
def hello
puts "Konnichiwa"
end
def goodbye
puts "Sayōnara"
end
end
class Person
include JapaneseGreetings
end
p = Person.new
p.hello # Output: Konnichiwa
p.goodbye # Output: Sayōnara
クラスはモジュールです
すべてのクラスは、クラスと呼ばれる組み込みクラスのインスタンスですか? Class は Module (別の組み込みクラス) のサブクラスです。
Class.superclass # Output: => Module
クラスの操作に使用される組み込みメソッドのほとんどは、Module クラスで定義されています。
Module.instance_methods(false)
=> [:<=>, :module_exec, :class_exec, :<=, :>=, :==, :===, :include?, :included_modules, :ancestors, :name,
:public_instance_methods, :instance_methods, :private_instance_methods, :protected_instance_methods, :const_get,
:constants, :const_defined?, :const_set, :class_variables, :class_variable_get, :remove_class_variable,
:class_variable_defined?, :class_variable_set, :private_constant, :public_constant, :singleton_class?,
:deprecate_constant, :freeze, :inspect, :module_eval, :const_missing, :prepend, :method_defined?, :class_eval,
:public_method_defined?, :private_method_defined?, :<, :public_class_method, :>, :protected_method_defined?,
:private_class_method, :to_s, :autoload, :autoload?, :instance_method, :public_instance_method, :include]
スーパークラスに「汎用」コード (さまざまなコンテキストで使用できる) を実装し、サブクラス内に特別な特殊化を追加するのが標準的な方法です。例として、Class クラスが Module クラスから上記のすべてのインスタンス メソッドを継承し、3 つの追加メソッドを実装する方法を示します。
Class.instance_methods(false)
=> [:new, :allocate, :superclass]
allocate メソッドは、メモリを割り当て、initialize メソッドを呼び出さずに、クラスの新しい「空の」インスタンスを作成します。new メソッドは allocate を呼び出してから、新しく作成されたオブジェクトの initialize メソッドを呼び出します。スーパークラスに関しては、指定されたクラスのスーパークラスの名前を返します。
彼の著書 The Ruby Programming Language で、松本幸宏 (Ruby の作成者、別名 Matz) は、新しいメソッドが Ruby で書かれた場合にどのようになるかを示しています。
def new(*args)
o = self.allocate # Create a new object of this class
o.initialize(*args) # Call the object's initialize method with our args
o # Return new object; ignore return value of initialize
end
簡単に言えば、クラスは、継承とインスタンス化という 2 つの重要な追加機能を備えたモジュールであると言えます。もう 1 つの違いは、モジュールとは異なり、クラスを mixin として使用できないことです。