使用Ruby中的相同模块多次扩展对象

时间:2016-03-24 11:18:31

标签: ruby

给定此类Klass和此类的实例k

class Klass
  def hello
    'Hello'
  end
end

k = Klass.new
k.hello        #=> "Hello"

我可以extend这个实例用一个模块向这个特定实例添加方法而不改变整个类(即所有实例):

module Mod
  def hello
    "#{super}, World!"
  end
end

k.extend(Mod)
k.hello        #=> "Hello, World!"

但是如果我使用相同的模块多次扩展k会怎样?

k.extend(Mod)
k.extend(Mod)
k.extend(Mod)
k.hello        #=> "Hello, World!"

后续调用是否被忽略或对象是否被多次扩展?

换句话说:多次扩展对象是否“安全”?

2 个答案:

答案 0 :(得分:5)

我认为后续的调用会被忽略(除非你有更深入的思考)。以下结果仅在祖先列表中显示Mod一次。

class Klass; end
module Mod; end
k = Klass.new
k.extend(Mod)
k.extend(Mod)
k.extend(Mod)
k.singleton_class.ancestors
# => [#<Class:#<Klass:0x007f7787ef7558>>, Mod, Klass, Object, Kernel, BasicObject]

答案 1 :(得分:5)

sawa already answered实际问题,但这也可能是相关的。虽然Mod只添加一次到对象(单例类&#39;)祖先,但每次调用extended回调:

class Klass
end

module Mod
  def self.extended(mod)
    puts "#{self} extended in #{mod}"
  end
end

k = Klass.new
k.extend(Mod)
#=> "Mod extended in #<Klass:0x007fabbb029450>"
k.extend(Mod)
#=> "Mod extended in #<Klass:0x007fabbb029450>"
k.extend(Mod)
#=> "Mod extended in #<Klass:0x007fabbb029450>"