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
Ruby 当散列';内容的变化_Ruby_Hash - Fatal编程技术网

Ruby 当散列';内容的变化

Ruby 当散列';内容的变化,ruby,hash,Ruby,Hash,当散列的内容发生变化时,我不想做什么。我对散列进行了子分类,并对方法[]=进行了如下重写: def []= (key,val) super(key,val) puts 'do something' end 但是当我调用merge时,它不起作用。正确的方法是什么?我必须覆盖所有更新哈希的方法吗?请记住返回访问的值,并覆盖合并方法: def []= (key,val) out = super(key,val) puts 'do something' out end def m

当散列的内容发生变化时,我不想做什么。我对
散列
进行了子分类,并对方法
[]=
进行了如下重写:

def []= (key,val)
  super(key,val)
  puts 'do something'
end

但是当我调用
merge
时,它不起作用。正确的方法是什么?我必须覆盖所有更新哈希的方法吗?

请记住返回访问的值,并覆盖
合并
方法:

def []= (key,val)
  out = super(key,val)
  puts 'do something'
  out
end

def merge(hash)
  out = super
  puts 'do something'
  out
end

请考虑使用另一种解决方案,因为MuneKy修补核心类是一种可怕的做法,这可能导致未定义的行为(如您的代码>合并< /代码>方法失败)。 请尝试改用继承:

class MyHash < Hash
  def []= (key,val)
    out = super(key,val)
    puts 'do something'
    out
  end

  def merge(hash)
    out = super(hash)
    puts 'do something'
    out
  end
end

# Usage
hash = MyHash.new
hash['a'] = 42 # prints 'do something'
class MyHash


要获得更优雅的解决方案,您可能需要检查gem。

因为您不关心性能,所以可以包装冻结的哈希并将所有方法(抢救、报告和更新另一个副本)委托给包装冻结的实例

class MyHash < BasicObject
  def initialize(hash = {})
    hash! hash
  end

  def hash!(hash)
    @hash = hash.freeze
  end

  def method_missing(m, *args, &λ)
    hash.send(m, *args, &λ)
  rescue => e
    raise e unless e.message.ends_with?('frozen Hash')

    # modification attempt was made
    puts 'do something'
    hash!(@hash.dup.send(m, *args, &λ)
  end
end
类MyHashe
提高e,除非e.message.以?(“冻结哈希”结尾)
#进行了修改尝试
“做点什么”
搞砸(@hash.dup.send(m,*args,&λ)
结束
结束

未经测试,但您已经有了主意。

当您调用
merge
时,您调用的是
merge
,而不是
[]=
@AndreyDeineko,因此我想在哈希的内容发生变化时调用一个方法,无论是通过
[]=
合并
旁注:子类化
散列
是一个非常糟糕的主意,因为ruby散列是高度优化的,这种方法会破坏一切,将ruby代码预先添加到普通的good
c
调用中。需要指出的是,当任何值发生变化时,这种解决方案离监控还有很长的路要走!…那么呢e> Hash#compact!
Hash#delete
Hash#delete#if
Hash#keep#if!
Hash#select!
Hash#store store
Hash#transform u#value!
Hash#转换#值!
Hash#更新#,我可能遗漏了更多的代码。)非常感谢。我还要指出,重写
散列#合并
(与
散列#合并相反)
)可能是不必要的-因为此方法正在创建新哈希,而不是对现有哈希进行变异。OP要求在哈希更改时执行某些操作,而不是在方法丢失时;您的代码将对尝试的任何方法执行“something”,即使该方法本身不更改哈希(即
[]
运算符)。您可以创建一个方法列表来修改散列的内部状态,并在
方法\u missing
中进行检查。我认为最好在执行时覆盖所需的方法。@Wikiti如果该方法不更改散列,
rescue
子句将被成功绕过,因为
freeze
契约将不会被违反。有趣的是,这是一种防止修改的聪明方法。但是,即使方法不存在,它仍然会执行“do something”代码。在尝试发送它之前,您可能应该检查
@hash
是否响应缺少的方法。@Wikiti是的,因为我认为这种方法没有任何价值,所以我坚持t发布了一个搭建的解决方案;添加了一个明确的检查异常是否是“我们的”