Reputation: 114188
Given a class Klass
and an instance k
of this class:
class Klass
def hello
'Hello'
end
end
k = Klass.new
k.hello #=> "Hello"
I can extend
this instance with a module to add methods to this specific instance without altering the whole class (i.e. all instances):
module Mod
def hello
"#{super}, World!"
end
end
k.extend(Mod)
k.hello #=> "Hello, World!"
But what happens if I extend k
multiple times with the same module?
k.extend(Mod)
k.extend(Mod)
k.extend(Mod)
k.hello #=> "Hello, World!"
Are the subsequent calls ignored or is the object extended multiple times?
To put it another way: is it "safe" to extend an object multiple times?
Upvotes: 1
Views: 1545
Reputation: 168131
I think the subsequent calls are ignored (unless you have something deeper in mind). The following result shows Mod
only once in the ancestor list.
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]
Upvotes: 7
Reputation: 114188
sawa already answered the actual question, but this could be relevant, too. Although the Mod
is added only once to the object's (singleton class') ancestors, the extended
callback is called every time:
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>"
Upvotes: 7