0

我的目标是找到一种在层次结构之间BasicObjectObject层次结构中插入我自己的类(或模块,因为它可能会变成)的方法,以便所有Objects现在都从我的类继承(或表现得像我的模块)。这是我的测试设置:

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通过打开Object类和包含来将行为添加到所有对象Entity,那么不仅所有对象都继承Entity的实例方法,而且它们也将它们作为单例方法继承。

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

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

这不是我想要的。我希望所有对象都Entity完全按照定义的方式继承定义的行为,以便Object继承Entity的实例方法和继承自Object继承Entity的单例方法的类,就像标准继承一样。我怎样才能修改我为实现这一目标所做的工作?

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 回答