Ruby模块前置与派生

时间:2014-07-23 10:48:42

标签: ruby

有什么区别:

module Mod   
   def here
     puts 'child'
   end    
end

class A
  prepend Mod
  def here
    puts 'parent'
  end
end

class A
   def here
     puts 'parent'
   end
end

class B < A
  def here
    puts 'child'
  end
end

或者另外一种方式:派生一个类与预先添加孩子代码的模块一样?

2 个答案:

答案 0 :(得分:3)

不,不是。 B只能从一个类继承,但Mod可以添加到许多类中。如果您要在super内拨打B#here,它将始终引用A#here,但在Mod#here内,它将引用#here实例方法无论什么类Mod被添加到:

module Mod   
  def here
    super + ' Mod'
  end    
end

class A
  prepend Mod
  def here
    'A'
  end
end

class B
  prepend Mod
  def here
    'B'
  end
end

A.new.here
# => 'A Mod'

B.new.here
# => 'B Mod'

class A
  def here
    'A'
  end
end

class B
  def here
    'B'
  end
end

class C < A
  def here
    super + ' C'
  end
end

C.new.here
# => 'A C'

class C < B
  def here
    super + ' C'
  end
end
# TypeError: superclass mismatch for class C

答案 1 :(得分:1)

不,这完全不同。

可以根据需要添加任意数量的模块。

module A
  def foo; "A" end
end

module B
  def foo; "B" end
end

class C
  prepend A, B   # Prepending is done by this line

  def foo; "C" end
end
### take a look at it!
C.ancestors # => [A, B, C, Object, Kernel, BasicObject]
C.new.foo # => "A"

Ruby使用不同的方式实现prepend和继承。 {em}包含模块在内部实现prepend,这会导致令人惊讶的ancestors

here是关于prepend的另一个问题,可能会有所帮助。