ruby – 通过在另一个模块中混合来覆盖模块Mixin行为

我希望能够来回切换实例如何响应消息.我希望通过混合模块,然后在另一个模块中混合以覆盖该行为来实现.

例:

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

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...