如何在ruby模块中保持状态?

时间:2014-01-24 12:49:44

标签: ruby module scope

这是一个示例模块,其行为类似于哈希:

module Hashlike
  def store key, value
    (@hash ||= {})[key] = value
  end

  def retrieve key
    (@hash ||= {})[key]
  end
end

包含它的课程:

class MyHash
  include Hashlike
end

现在这很好用,我可以从一个实例存储和检索:

> my_hash = MyHash.new
=> #<MyHash:0xc1808d8>
> my_hash.store :a, 1
=> 1
> my_hash.retrieve :a
=> 1

不幸的是,实例现在有一个来自模块的实例变量@hash。这可能与现有的实例变量发生冲突:

> my_hash.instance_variable_get '@hash'
=> {:a=>1}

限制模块中定义的实例变量范围的最佳方法是什么不会混淆包括这些模块在内的实例的范围?

换句话说,模块应该在哪里保持状态?

1 个答案:

答案 0 :(得分:4)

我只需重命名实例变量以减少碰撞的几率。

module Hashlike
  def store(key, value)
    _hash[key] = value
  end

  def retrieve(key)
    _hash[key]
  end

  private
  def _hash
    @_hashlike_storage ||= {}
  end
end

class MyHash
  include Hashlike
end

my_hash = MyHash.new
my_hash.store :a, 1 # => 1
my_hash.retrieve :a # => 1
my_hash.instance_variables # => [:@_hashlike_storage]