Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用mixin(或特征类,或其他方法),有没有一种方法可以模拟向对象添加新的超类?_Ruby_Inheritance_Mixins - Fatal编程技术网

Ruby 使用mixin(或特征类,或其他方法),有没有一种方法可以模拟向对象添加新的超类?

Ruby 使用mixin(或特征类,或其他方法),有没有一种方法可以模拟向对象添加新的超类?,ruby,inheritance,mixins,Ruby,Inheritance,Mixins,我的目标是在层次结构中的BasicObject和Object之间插入我自己的类(或模块,可能是这样),这样所有对象现在都从我的类继承(或表现得像我的模块)。这是我的测试设置: module Entity # Define the singleton method Entity::new such that it generates and returns # a class which extends Entity. def self.new(*args, &blk)

我的目标是在层次结构中的
BasicObject
Object
之间插入我自己的类(或模块,可能是这样),这样所有
对象现在都从我的类继承(或表现得像我的模块)。这是我的测试设置:

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
如果我随后创建一个类
Thing
,其中
包含
s
实体
,我将接近我想要的输出:

thing = Thing.new
thing.bar #=> bar
Thing.foo #=> NoMethodError
Thing
的实例继承了我在
Entity
中定义的实例方法,但不幸的是类
Thing
没有继承
Entity
的单例方法

如果我试图通过打开
对象
类并包含
实体
,将
实体
行为添加到所有对象中,那么所有对象不仅继承
实体
的实例方法,而且还作为单例方法继承它们

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

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

这不是我想要的。我希望所有对象都能继承
实体
中定义的行为,使
对象
的实例继承
实体
的实例方法,以及继承
对象
的类继承
实体
的单例方法,就像标准继承一样。我如何修改我所做的来实现这一点?

您所描述的正常模式是这样做:

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
模块MyModule
定义一些_实例_方法
结束
模块类方法
定义一些类方法
结束
结束
包括def自身(其他MOD)

类您描述的正常模式是这样做:

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
模块MyModule
定义一些_实例_方法
结束
模块类方法
定义一些类方法
结束
结束
包括def自身(其他MOD)
class既定的方法(特别是Rails人员)是将单例方法定义为某个模块的实例方法,并使用
包含的
钩子
扩展

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的答案几乎相同,但有点不同。

既定的方法(尤其是Rails人员)是将单例方法定义为某些模块的实例方法,并使用包含的
钩子
扩展

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


这与多伊德尔的答案几乎相同,但有点不同。

谢谢!我将尝试一下。我已经尝试过了,但是它允许类
Bob
Bob
的实例都可以访问
some_-instance_-method
Bob.some_-instance_-method
Bob.new.some_-instance_-method=>nil
很抱歉我的评论格式有问题,我搞不懂如何在评论中删除代码块。请给我们看一下你的新代码好吗?很难说还有什么不对当然,我把它作为一个新问题发布了,因为…因为现在这是一个新问题哈哈。谢谢我将尝试一下。我已经尝试过了,但是它允许类
Bob
Bob
的实例都可以访问
some_-instance_-method
Bob.some_-instance_-method
Bob.new.some_-instance_-method=>nil
很抱歉我的评论格式有问题,我搞不懂如何在评论中删除代码块。请给我们看一下你的新代码好吗?很难说还有什么不对当然,我把它作为一个新问题发布了,因为…因为现在这是一个新问题哈哈。如果我对
extend
的理解是正确的,那么这不正是Doydle所做工作的简写吗?这就是你所说的“稍微不同”的意思,还是它的行为确实有点不同?使用这种方法似乎会产生与Doydle建议相同的行为。这种行为几乎就是我想要的,除了我不希望从
对象
继承的类继承
我的实例方法
作为特征方法。事实上,该行为明确地防止了
ClassMethods
中定义的实例方法被继承为实例方法,这是一件好事。
因此扩展了
方法,除非
Baz.singleton\u class.send:include,Foo
并没有创建singleton类?如果我对
extend
的理解是正确的,那它不就是Doydle所做的事情的简写吗?这就是你所说的“稍微不同”的意思,还是它的行为确实有点不同?使用这种方法似乎会产生与Doydle建议相同的行为。这种行为几乎就是我想要的,除了我不希望从
对象
继承的类继承
我的实例方法
作为特征方法。实际上,该行为明确地防止了
ClassMethods
中定义的实例方法被继承为实例方法,这是一件好事。
因此
扩展了
方法,除非
Baz.singleton\u class.send:include,Foo
没有创建singleton类?