Ruby中的Track Array更改



我想知道,是否有一种简单的方法可以实现行为类似于ActiveModel::Dirty的Ruby数组,所以我可以做到:

array = [1,2]
array.changed? # => false
array << 5
array.changed? # => true

到目前为止,我唯一的想法是实现TrackedArray < ArrayTrackedArray < DelegateClass(Array),通过Array的公共API,为每个带有感叹号的方法和其他方法(如keep_if<<等)调用define_method,并设置一个@changed_marker = true

这样,我将为每个数组实例获得changed? == true,它被更改了一次,但如果在对象上撤消更改,它将不会返回到changed? == false。因此它不能完全兼容CCD_ 10。

对于一个笨拙的实现来说,这似乎是一项巨大的努力。。。

Naiëve实现(只是出于好奇):

class Hurray
  attr_accessor :dirty
  def initialize *args, &cb
    @array = Array.new *args, &cb
    @dirty = false
  end
  def method_missing m, *args, &cb
    @dup = @array.dup
     # maybe public_send, maybe whitelist methods
    @array.send(m, *args, &cb).tap do
      @dirty |= @dup != @array
    end
  end
end      

可以使attr_reader :dup也可以在修改数组之前访问数组的最后一个副本,例如undo

最新更新