module Person
def name
"My name belongs to Person"
end
end
class User
include Person
def name
"My name belongs to User"
end
end
puts User.new.name
=> My name belongs to User
现在再来看看 prepend 的情况:
module Person
def name
"My name belongs to Person"
end
end
class User
prepend Person
def name
"My name belongs to User"
end
end
puts User.new.name
=> My name belongs to Person
使用 prepend Person 会将 User 中的同名方法给覆盖掉,因此在终端输出的结果为 My name belongs to Person。 prepend 实际上是将方法添加到方法链的前端。在调用 User 类内定义的 name 方法时,会调用 super 从而调用 Person 模块的 name。
与 prepend 对应的回调名为(你应该猜到了) prepended。当一个模块被预置到另一个模块/类中时它会被调用。 我们来看下效果。更新 Person 模块的定义:
module Person
def self.prepended(base)
puts "#{self} prepended to #{base}"
end
def name
"My name belongs to Person"
end
end
你再运行这段代码应该会看到如下结果:
Person prepended to User
My name belongs to Person
prepend 的引入是为了去除 alias_method_chain hack的丑陋,它曾被Rails以及其他库广泛地使用以达到与 prepend 相同的功能。 因为 prepend 只有在 Ruby >= 2.0 的版本中才能使用,因此如果你打算使用 prepend 的话,那么你就应该升级你的Ruby版本。
inherited
继承是面向对象中一个最重要的概念。Ruby是一门面向对象的编程语言,并且提供了从基/父类继承一个子类的功能。 我们来看一个简单的例子:
class Person
def name
"My name is Person"
end
end
class User < Person
end
puts User.new.name # => My name is Person
我们创建了一个 Person 类和一个子类 User。在 Person 中定义的方法也成为了 User 的一部分。 这是非常简单的继承。你可能会好奇,是否有什么方法可以在一个类被其他类继承时收到通知呢? 是的,Ruby有一个名为 inherited 的钩子可以实现。我们再看看这个例子:
class Person
def self.inherited(child_class)
puts "#{child_class} inherits #{self}"
end
def name
"My name is Person"
end
end










