加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-17 03:07:37 所属栏目:百科 来源:网络整理
导读:我希望能够来回切换实例如何响应消息.我希望通过混合模块,然后在另一个模块中混合以覆盖该行为来实现. 例: module Dog def speak puts "woof woof" endendmodule Cat def speak puts "meow" endendclass Animalend 现在我想来回切换,Animal的一个实例如何响
我希望能够来回切换实例如何响应消息.我希望通过混合模块,然后在另一个模块中混合以覆盖该行为来实现.

例:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读