Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
";仅附加“/quot;”&引用;只写“;Ruby中的hash_Ruby_Hashmap_Ruby Hash_Writeonly - Fatal编程技术网

";仅附加“/quot;”&引用;只写“;Ruby中的hash

";仅附加“/quot;”&引用;只写“;Ruby中的hash,ruby,hashmap,ruby-hash,writeonly,Ruby,Hashmap,Ruby Hash,Writeonly,我正在寻找一种“仅附加”哈希,其中键只能设置一次 例如: capitals = AppendOnlyHash.new capitals['france'] = 'paris' capitals['japan'] = 'tokyo' capitals['france'] = 'nice' # raises immutable exception 图书馆有什么建议或想法如何实现这一点 (用例是一个日志类型的对象,它将被传递给numerouis松散连接的类,并希望检测是否有使用相同密钥的对象。)首先

我正在寻找一种“仅附加”哈希,其中键只能设置一次

例如:

capitals = AppendOnlyHash.new
capitals['france'] = 'paris'
capitals['japan'] = 'tokyo'
capitals['france'] = 'nice' # raises immutable exception
图书馆有什么建议或想法如何实现这一点


(用例是一个日志类型的对象,它将被传递给numerouis松散连接的类,并希望检测是否有使用相同密钥的对象。)

首先,我没有考虑任何缺点:

class HashImmutable < Hash
  def []=(key,val)
    if self[key].frozen?
      super(key,val)
    else
      # self[key]
      raise 'Immutable'
    end
  end
end

hh = HashImmutable.new

hh[:france] = 'Paris'
hh[:italy] = 'Roma'
hh #=> {:france=>"Paris", :italy=>"Roma"}
hh[:italy] = 'Brescia'
#=> Immutable (RuntimeError)
类HashImmutable{:法国=>“巴黎”,意大利=>“罗马”}
hh[:意大利]=“布雷西亚”
#=>不可变(运行时错误)

下面是创建此类类的一个天真尝试。对于“基本”用法,它似乎很好:

您可以在每个值添加到散列中时调用
.freeze
,但即使这样也不是100%防弹的,因为该值可能是另一个
散列
,它也会受到相同行为的影响



总之,我认为通过我上面的基本实现,这是可能的,但我会谨慎对待由“奇怪的方式”的对象突变导致的日益复杂的边缘情况。

有10种方法,直接突变哈希:

Hash.instance_methods.grep(/.+!\z/) << %i|[]= delete keep_if|
#⇒ [:select!, :filter!, :reject!, :compact!, delete, keep_if,
#   :transform_keys!, :transform_values!, :merge!, :[]=]

Hash.instance\u methods.grep(/.+!\z/)我担心的是,哈希可能会以其他方式更新。除了
[]
之外,还有一些方法可以改变散列。也许您可以将这些方法添加到类中,例如
def transform_values!;提出"一成不变",;结束
奇怪的是,现在还没有rubygem来做这件事。
capitals = AppendOnlyHash.new
str = "paris"
capitals['france'] = str
str << " CHANGED"
Hash.instance_methods.grep(/.+!\z/) << %i|[]= delete keep_if|
#⇒ [:select!, :filter!, :reject!, :compact!, delete, keep_if,
#   :transform_keys!, :transform_values!, :merge!, :[]=]
class MyHash < Hash; end

MyHash.prepend(
  Module.new do
    (Hash.instance_methods.grep(/.+!\z/) | %i|delete keep_if|).each do |method|
      define_method(method) do |*args|
        raise "Method #{method} is restricted since it is mutating"
      end
    end
    def []=(key, val)
      raise "This hash is immutable" if key?(key)
      super(key, val.freeze) # to prevent inplace mutations
    end
  end
)