红宝石包括问题

时间:2009-10-29 17:42:10

标签: ruby

class Foo
  def initialize(a)
    puts "Hello #{a}"
  end
end
module Bar
  def initialize(b)
    puts "#{b} World"
  end
end
class Sample < Foo
  include Bar
  def initialize(c)
    super
  end
end
Sample.new('qux') #=> qux World

为什么输出不是'Hello qux'? credit for code

2 个答案:

答案 0 :(得分:10)

当你将一个模块包含在一个类中时,它就像你在类层次结构中插入一个新的超类一样,就在Sample和Foo之间。调用super()通过包含的模块进行搜索,然后再回到真正的超类(Foo)。

答案 1 :(得分:2)

简短的回答是,如果输出是“Hello World”,那将是绝对疯狂的谈话。根本没有任何意义的两个输出将是“Hello qux”或“qux World”。在这种情况下,“qux World”是输出,因为这是顺序:

  1. Sample延伸Fooinitialize继承自Foo
  2. Sample包括Barinitialize重写
  3. Sample定义initialize,调用super,指向最新祖先initialize的实现,在本例中为Bar的< / LI>

    这应该会更清楚:

    class Foo
      def initialize(a)
        puts "Hello #{a}"
      end
    end
    module Bar
      def initialize(b)
        super # this calls Foo's initialize with a parameter of 'qux'
        puts "#{b} World"
      end
    end
    class Sample < Foo
      include Bar
      def initialize(c)
        super # this calls Bar's initialize with a parameter of 'qux'
      end
    end
    Sample.new('qux')
    

    输出:

    Hello qux
    qux World