在Object中的模块中混合会导致所有对象将该模块的实例方法作为单例方法继承

时间:2013-07-16 21:19:28

标签: ruby include extend mixins monkeypatching

当我尝试将自己的行为添加到Object类时,我会得到在将模块混合到用户定义的类时不会发生的不良影响。

module Entity
  def some_instance_method
    puts 'foo'
  end

  def self.secret_class_method
    puts 'secret'
  end

  module ClassMethods
    def some_class_method
      puts 'bar'
    end
  end

  def self.included( other_mod )
    other_mod.extend( ClassMethods )
  end
end

现在,我创建了一个类Bob,使其包含Entity

class Bob; include Entity; end;

这产生了期望和预期的输出:

Bob.secret_class_method       #=> NoMethodError
Bob.some_instance_method      #=> NoMethodError
Bob.some_class_method         #=> bar
Bob.new.secret_class_method   #=> NoMethodError
Bob.new.some_instance_method  #=> foo
Bob.new.some_class_method     #=> NoMethodError

但是,如果不是定义课程Bob,而是打开课程Object并像这样包含Entity

class Object; include Entity; end

然后我看到的输出是:

Object.secret_class_method        #=> NoMethodError
Object.some_instance_method       #=> foo
Object.some_class_method          #=> bar
Object.new.secret_class_method    #=> NoMethodError
Object.new.some_instance_method   #=> foo
Object.new.some_class_method      #=> NoMethodError

如果我然后定义类Bob,它的行为方式相同:some_instance_method可以在类Bob上调用。似乎Object类本身的某些东西正在弄乱这种模式的行为,否则我只是在这里做错了。有人可以解释这个奇怪的行为吗?我不希望我的所有Object都将实例方法作为单例方法继承!

1 个答案:

答案 0 :(得分:1)

Bob ia是一个对象(更确切地说:BobClass的一个实例,它是Module的子类,是Object的子类,它是Entity)的子类,因此它有Entity的方法。这就是继承的工作原理。