0

私は自分のクラス (またはモジュールのように振る舞う)を階層の間BasicObjectに挿入する方法を目指しています (または、モジュールのように動作します)。これは私のテスト設定です:ObjectObjects

module Entity
  # Define the singleton method Entity::new such that it generates and returns
  # a class which extends Entity.
  def self.new(*args, &blk)
    c = Class.new(*args, &blk)
    c.extend self
    c
  end

  # Singleton method
  def self.foo
    puts 'foo'
  end
  # Instance method
  def bar
    puts 'bar'
  end
end

次に、 s のクラスThingを作成すると、希望する出力に近づきます。includeEntity

thing = Thing.new
thing.bar #=> bar
Thing.foo #=> NoMethodError

のインスタンスは でThing定義したインスタンス メソッドを継承しますEntityが、クラスは残念ながらThingのシングルトン メソッドを継承しません。Entity

クラスEntityを開いて を含めてすべてのオブジェクトに動作を追加しようとすると、すべてのオブジェクトが のインスタンス メソッドを継承するだけでなく、シングルトン メソッドとしても継承します。ObjectEntityEntity

class Object; include Entity; end
Object.bar     #=> bar
Object.new.bar #=> bar

class Bob; end
Bob.bar        #=> bar
Bob.new.bar    #=> bar

これは私が欲しいものではありません。すべてのオブジェクトが で定義されている動作を定義Entityどおりに継承するようにしたいので、Objectinheritのインスタンス メソッドのインスタンスと、標準の継承と同様に、inheritのシングルトン メソッドEntityから継承するクラスが生成されます。これを達成するために行ったことをどのように変更できますか?ObjectEntity

4

2 に答える 2

2

あなたが説明していることの通常のパターンは、次のようなことです:

module MyModule
    def some_instance_method
    end

    module ClassMethods
        def some_class_method
        end
    end

    def self.included(othermod)
        class << othermod
            include ClassMethods
        end
    end
end

モジュールが別のクラスにインクルードされるたびに、インクルードされたメソッドが呼び出され、ClassMethods 内のメソッドがクラスのメタクラスにインクルードされます。

于 2013-07-16T15:38:12.083 に答える
1

(特に Rails の人々の間で) 確立された方法は、シングルトン メソッドを何らかのモジュールのインスタンス メソッドとして定義し、クラスへのincludedフックをそれらと共に使用することです。extend

module Entity
  def my_instance_method; ... end
  def self.included base; base.extend(ClassMethods) end
  module ClassMethods
    def my_class_method; ... end
  end
end

これは Doydle の回答とほぼ同じですが、少し異なります。

于 2013-07-16T15:43:41.450 に答える