Ruby module prepend vs derivation

2020-07-11 06:42发布

What are the differences between:

module Mod   
   def here
     puts 'child'
   end    
end

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

and

class A
   def here
     puts 'parent'
   end
end

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

Or another way to put it: is derivating a class the same as prepending a module of the child's code?

标签: ruby
2条回答
够拽才男人
2楼-- · 2020-07-11 07:12

No, it is not. B can only inherit from one class, but Mod can be prepended to many classes. If you were to call super inside B#here, it would always refer to A#here, but inside of Mod#here, it will refer to the #here instance method of whatever class Mod was prepended to:

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'

and

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
查看更多
The star\"
3楼-- · 2020-07-11 07:18

No, it's totally different.

One can prepend as many modules as he wants.

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 implements prepend and inheritance using different ways. prepend is internally achieved by including modules, which causes the surprising ancestors.

here is another question about prepend which may be helpful.

查看更多
登录 后发表回答