ruby - ruby 中的适配器模式 : Accessing Your Instance Variables

标签 ruby

我正在学习adapter pattern在 ruby 中的实现。我想访问适配器模块定义中的实例变量。看一下下面的代码:

module Adapter
  module Dog
    def self.speak
      # I want to access the #name instance variable from my Animal instance
      puts "#{name} says: woof!"
    end
  end

  module Cat
    def self.speak
      # I want to access the #name instance variable from my Animal instance
      puts "#{name} says: meow!"
    end
  end
end

class Animal
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def speak
    self.adapter.speak
  end

  def adapter
    return @adapter if @adapter
    self.adapter = :dog
    @adapter
  end

  def adapter=(adapter)
    @adapter = Adapter.const_get(adapter.to_s.capitalize)
  end
end

为了测试它,我做了以下操作:

animal = Animal.new("catdog")
animal.adapter = :cat
animal.speak

我希望它返回以下内容:

catdog says: meow!

相反,它说:

Adapter::Cat says: meow!

有关如何从适配器模块访问 Animal#name 实例方法的任何提示?我认为问题在于我的适配器方法是类级方法。

谢谢!

最佳答案

您需要使用您的模块作为 mixin 并提供一种方法来跟踪哪个模块处于事件状态,这些方法似乎不会通过重新包含或重新扩展而被覆盖,因此我采用了我发现的扩展和删除方法 here

module Adapter
  module Dog
    def speak
      puts "#{name} says: woof!"
    end
  end

  module Cat
    def speak
      puts "#{name} says: meow!"
    end
  end

  def extend mod
    @ancestors ||= {}
    return if @ancestors[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 Adapter
  attr_accessor :name, :adapter

  def initialize(name)
    @name = name
    @adapter = Adapter::Dog
    extend Adapter::Dog
  end

  def adapter=(adapter)
    remove @adapter
    extend Adapter::const_get(adapter.capitalize)
    @adapter = Adapter.const_get(adapter.capitalize)
  end
end

animal = Animal.new("catdog")
animal.speak # catdog says: woof!
animal.adapter = :cat
animal.speak # catdog says: meow!
animal.adapter = :dog
animal.speak # catdog says: woof!

关于ruby - ruby 中的适配器模式 : Accessing Your Instance Variables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41861791/

相关文章:

java - 使用 Ruby 将文件复制到 jar 文件中

RubyMine - 关键字 'require' 显示为红色,但应用程序运行正常

php - 获取 Ruby 的 OpenSSL::HMAC.hexdigest() 的输出与 PHP 的 hash_hmac() 相同

ruby-on-rails - 如何向 Rails 5 中的现有类添加方法?

ruby - 新的 Ruby 1.9 哈希语法

ruby - 混淆 `===` 和 `.===` 的工作

jquery - 在 ruby​​ on rails 中进行 ajax 调用时,什么时候使用数据属性是不好的做法?

ruby - 用ruby中的数组内容替换字符串?

ruby-on-rails - Ruby on Rails 路径助手

irb 中的 Ruby 字符串比较和字符编码