我希望能够来回切换实例如何响应消息.我希望通过混合模块,然后在另一个模块中混合以覆盖该行为来实现.
例:
module Dog def speak puts "woof woof" end end module Cat def speak puts "meow" end end class Animal end
现在我想来回切换,Animal的一个实例如何响应发言信息:
animal = Animal.new animal.extend(Cat) animal.speak animal.extend(Dog) animal.speak animal.extend(Cat) animal.speak animal.extend(Dog) animal.speak animal.extend(Cat) animal.speak
meow woof woof meow woof woof meow
相反,它输出如下:
meow woof woof woof woof woof woof woof woof
有关如何使其按预期工作的任何提示?
解决方法
我在
Adapter Pattern in ruby: Accessing Your Instance Variables的另一个问题上修改了答案
module Dog def speak puts "woof woof" end end module Cat def speak puts "meow" end end module Module_manager attr_accessor :name def extend mod @ancestors ||= {} return if @ancestors[mod] remove @name if @name @name = mod mod_clone = mod.clone @ancestors[mod] = mod_clone super mod_clone end def remove mod mod_clone = @ancestors[mod] mod_clone.instance_methods.each {|m| mod_clone.module_eval {remove_method m } } @ancestors[mod] = nil end end class Animal include Module_manager end animal = Animal.new animal.extend(Cat) animal.speak # meow animal.extend(Dog) animal.speak # woof woof animal.extend(Cat) animal.speak # meow animal.extend(Dog) animal.speak # woof woof animal.extend(Cat) animal.speak # meow