16

私は Ruby について調べていて、その mixins パターンについて学びましたが、多くの有用な mixin 機能を思いつきませんでした (おそらく、そのように考えることに慣れていないため)。では、便利な Mixin 機能の良い例は何だろうと思っていました。

ありがとう

編集:少し背景。私は C++ やその他のオブジェクト言語から来ていますが、Ruby はミックスインを継承していないと言っているのではないかと疑っています。 、ミックスインが何であるかを実際には理解していません。

4

4 に答える 4

12

これらは通常、すべてを再定義することなく、何らかの形式の標準機能をクラスに追加するために使用されます。Java のインターフェースに少し似ていると考えることができますが、実装する必要があるメソッドのリストを定義するだけでなく、それらの多くはモジュールを含めることで実際実装されます。

標準ライブラリにはいくつかの例があります:

Singleton - 任意のクラスに混合してシングルトンにすることができるモジュール. 初期化メソッドがプライベートになり、インスタンス メソッドが追加されます。これにより、アプリケーション内にそのクラスのインスタンスが 1 つだけ存在することが保証されます。

Comparable - このモジュールをクラスに含める場合、現在のインスタンスを別のオブジェクトと比較してどちらが大きいかを判断する <=> メソッドを定義するだけで、<、<=、==、>=、>、およびの間に?メソッド。

Enumerable - このモジュールを混合し、メソッドを定義することで、collect、inject、select、reject などの他のすべての関連メソッドをサポートできます。<=> メソッドもある場合は、sort、min、max もサポートされます。

DataMapper は、単純な include ステートメントで実行できることの興味深い例でもあり、標準クラスを取り、それをデータ ストアに永続化する機能を追加します。

于 2008-12-10T10:55:50.580 に答える
9

まあ、私が思う通常の例は持続性です

module Persistence
    def load sFileName
            puts "load code to read #{sFileName} contents into my_data"
    end
        def save sFileName
        puts "Uber code to persist #{@my_data} to #{sFileName}"
    end

end

class BrandNewClass
    include Persistence
    attr :my_data

        def data=(someData)
        @my_data = someData
    end
end

b = BrandNewClass.new
b.data = "My pwd"
b.save "MyFile.secret"
b.load "MyFile.secret"

モジュールがRuby忍者によって書かれ、クラスの状態をファイルに保持していると想像してください。
ここで、まったく新しいクラスを作成するとします。永続化の機能は、次のように混合して再利用できますinclude ModuleILike。実行時にモジュールを含めることもできます。混ぜるだけで、無料で load メソッドと save メソッドを取得できます。これらのメソッドは、クラス用に自分で作成したものとまったく同じです。コード/動作/機能 - 継承せずに再利用!

したがって、あなたがしているのは、クラスのメソッド テーブルにメソッドを含めることです (文字通り正しいわけではありませんが、近いです)。

于 2008-12-10T11:02:54.453 に答える
3

Ruby では、Mixin が多重継承ではない理由は、Mixin メソッドの組み合わせが 1 回限りのものだからです。これは、Ruby のモジュールとクラスが変更可能であることを除けば、それほど大きな問題にはなりません。これは、モジュールをクラスにミックスインしてからモジュールにメソッドを追加すると、そのメソッドはクラスで使用できなくなることを意味します。逆の順序で実行した場合は、そうなるでしょう。

アイスクリームコーンを注文するようなものです。ミックスインとしてチョコレート スプリンクルとタフィー ビッツを入手し、コーンを持って立ち去った場合、誰かがアイス クリーム ショップのチョコレート スプリンクル ビンに色とりどりのスプリンクルを追加しても、アイス クリーム コーンの種類は変わりません。mixinモジュールであるスプリンクルのビンが変更されている場合、クラスであるアイスクリームコーンは変更されません。その mixin モジュールを次に使用する人は、変更を確認できます。

includeRubyでモジュールを作成すると、そのモジュールが呼び出されModule#append_features、そのモジュールのメソッドのコピーがインクルーダーに1回追加されます。

私が理解しているように、多重継承は委譲に似ています。あなたのクラスが何かを行う方法を知らない場合、クラスは親に尋ねます。オープンクラス環境では、クラスの作成後にクラスの親が変更されている可能性があります。

RLの親子関係のようなものです。あなたの母親は、あなたが生まれた後にジャグリングを習ったかもしれません。彼女のジャグリング能力が生まれる前にあなたが作成されたとしても、その時点でできるようになります.

ruby モジュールの 'include' を変更Module#append_featuresして、インクルーダーのリストを保持するように変更し、method_addedコールバックを使用してそれらを更新することにより、多重継承のように振る舞うことができますが、これは標準の Ruby からの大きなシフトであり、原因となる可能性があります。他のコードで作業するときの主要な問題。委任Module#inheritも呼び出して処理するメソッドを作成する方がよい場合があります。include

実世界の例についてEnumerableは、素晴らしいです。を定義してクラスに#each含めるEnumerableと、すべてのイテレータをコーディングしなくても、イテレータのホスト全体にアクセスできるようになります。

于 2008-12-10T13:58:27.437 に答える
1

C++ で多重継承を使用したり、Java/C# でインターフェイスを実装したりする可能性があるため、主に使用されます。あなたの経験がどこにあるのかはわかりませんが、以前にそれらのことをしたことがあるなら、ミックスインは Ruby でそれらを行う方法です。これは、機能をクラスに注入する体系化された方法です。

于 2008-12-10T10:37:05.737 に答える