微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐