Ruby 的 prepend 和 prepened
本章节我们将讲解最后一种混入方式:prepend
。
1. prepend
prepend
是在 Ruby2.0 以后引入进来的,它的使用方式和include
非常类似,将模块中定义的方法添加进被添加的类的实例方法中。
实例:
module Person
def name
"My name is Andrew"
end
end
class Member
prepend Person
end
puts Member.new.name
# ---- 输出结果 ----
My name is Andrew
2. prepend 和 include 的区别
使用include
或者extend
引入的方法如果和被引入的模块/类中的方法重名,将不会覆盖被引入模块的方法,但是prepend
会覆盖被引入模块的方法。
下面是 include
的例子。
实例:
module Person
def name
"My name is Person"
end
end
class Member
include Person
def name
"My name is Andrew"
end
end
puts Member.new.name
# ---- 输出结果 ----
My name is Andrew
而 prepend
则是这个样子。
实例:
module Person
def name
"My name is Person"
end
end
class Member
prepend Person
def name
"My name is Andrew"
end
end
puts Member.new.name
# ---- 输出结果 ----
My name is Person
我们会发现,原本的 name
实例方法被覆盖了。
3. prepended
当类追加模块后,会触发prepended
钩子方法。
实例:
module Person
def self.prepended(klass)
puts "#{self} prepended to #{klass}"
end
def name
"My name is Andrew"
end
end
class Member
prepend Person
end
puts Member.new.name
# ---- 输出结果 ----
Person prepended to Member
My name is Andrew
解释:当模块Person
被追加后,触发了prepended
钩子方法,打印了“Person prepended to Member”。
4. 小结
本章节我们学习了prepend
,它和include
很像,都可以向类追加实例方法,不同的是,prepend
追加的方法的名称和类本身拥有的相同时,prepend
会覆盖原有的方法,include
则不会覆盖。另外,当一个模块被prepend
的时候,会触发prepended
回调,并返回操作的类名。